├── .gitignore ├── LICENSE ├── NOTES.md ├── README.md ├── changelog.txt ├── circuit.lua ├── compat └── pickerextended.lua ├── configchange.lua ├── control.lua ├── data-updates.lua ├── data.lua ├── graphics ├── entity │ ├── hr-miniloader-filter-inserter-base.png │ ├── hr-miniloader-filter-structure-base.png │ ├── hr-miniloader-filter-structure-front-patch.png │ ├── hr-miniloader-inserter-base.png │ ├── hr-miniloader-structure-back-patch.png │ ├── hr-miniloader-structure-base.png │ ├── hr-miniloader-structure-front-patch.png │ ├── hr-miniloader-structure-mask.png │ ├── hr-miniloader-structure-shadow.png │ ├── miniloader-filter-inserter-base.png │ ├── miniloader-filter-structure-base.png │ ├── miniloader-filter-structure-front-patch.png │ ├── miniloader-inserter-base.png │ ├── miniloader-structure-back-patch.png │ ├── miniloader-structure-base.png │ ├── miniloader-structure-front-patch.png │ ├── miniloader-structure-mask.png │ └── miniloader-structure-shadow.png ├── item │ ├── filter-icon-base.png │ ├── icon-base.png │ └── icon-mask.png └── technology │ ├── technology-base.png │ └── technology-mask.png ├── gui.lua ├── icon.png ├── icon2.png ├── icon3.png ├── info.json ├── locale ├── ca │ └── miniloader.cfg ├── cs │ └── miniloader.cfg ├── de │ └── miniloader.cfg ├── en │ └── miniloader.cfg ├── fr │ └── miniloader.cfg ├── it │ └── miniloader.cfg ├── ja │ └── miniloader.cfg ├── ko │ └── miniloader.cfg ├── pt-BR │ └── miniloader.cfg ├── ru │ └── miniloader.cfg ├── uk │ └── miniloader.cfg ├── zh-CN │ └── miniloader.cfg └── zh-TW │ └── miniloader.cfg ├── lualib ├── blueprint.lua ├── event.lua ├── miniloader.lua ├── ontick.lua ├── onwireplaced.lua └── util.lua ├── pack.sh ├── prototypes ├── entities.lua ├── items.lua ├── recipes.lua ├── technologies.lua └── templates.lua ├── resources ├── assemblerdemo.png ├── priority_split.png ├── rebalance.png ├── ups_cost.png └── wagon.png ├── settings.lua ├── snapping.lua ├── thumbnail.png └── version.lua /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.zip 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /NOTES.md: -------------------------------------------------------------------------------- 1 | ### Code to paste to setup testing 2 | 3 | ```lua 4 | /c 5 | local bar = game.player.get_inventory(defines.inventory.player_quickbar) 6 | bar.clear() 7 | for _, stack in ipairs{ 8 | "electric-energy-interface", 9 | "medium-electric-pole", 10 | "steel-chest", 11 | "iron-plate", 12 | "miniloader", 13 | "transport-belt", 14 | "fast-miniloader", 15 | "fast-transport-belt", 16 | "express-miniloader", 17 | "express-transport-belt", 18 | } do 19 | bar.insert(stack) 20 | end 21 | bar.insert("iron-plate") 22 | game.player.insert{name="iron-plate", count=500} 23 | game.player.insert{name="copper-plate", count=500} 24 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Miniloaders 2 | 3 | This mod introduces miniloaders, 1x1 entities that efficiently transfer a full 4 | belt worth of items into and out of containers, including train cargo wagons. 5 | 6 | ![Miniloaders in action with cargo wagons](resources/wagon.png) 7 | 8 | They use no Lua when running, keeping your factory's UPS healthy. 9 | 10 | ![Miniloader UPS usage](resources/ups_cost.png) 11 | 12 | You can use them to feed your high-speed assemblers, 13 | 14 | ![Miniloader assembler feed](resources/assemblerdemo.png) 15 | 16 | or put them in your bus as single-belt lane rebalancers. 17 | 18 | ![Miniloaders lane balancer](resources/rebalance.png) 19 | 20 | Belts from the following mods are fully supported: 21 | * Bob's Logistics 22 | * FactorioExtended Plus 23 | * Space Exploration 24 | * Ultimate Belts 25 | * Xander Mod 26 | * Random Factorio Things 27 | * Plutonium Energy 28 | 29 | ## Videos and Spotlights 30 | 31 | Xterminator has [spotlighted Miniloader](https://youtu.be/6aGD3fh2P5A). 32 | Seeeno has created a 33 | [video tutorial in German](https://www.youtube.com/watch?v=f16zRTtZSQA) for Miniloader. 34 | 35 | ## Balancing 36 | 37 | Miniloaders require stack inserter research, are relatively expensive to build, 38 | and consume approximately the power of two fully-upgraded stack inserters. 39 | 40 | ## How it works 41 | 42 | Each miniloader hides a set of very fast invisible inserters, one for each lane 43 | of the belt. Lua scripting adjusts pickup and drop points accordingly when the 44 | direction of the miniloader is changed. 45 | 46 | Since item movement is handled by inserters, there is no on_tick handler, no Lua 47 | impact on UPS, and miniloaders will benefit from any future improvements to belt 48 | and inserter performance made by Wube in the Factorio core. 49 | 50 | ## Filtering 51 | 52 | Versions of miniloaders with and without filtering are available once the 53 | appropriate technology has been researched. As you would expect, to build a 54 | miniloader capable of filtering, you must use filter inserters as ingredients. 55 | 56 | Note that filter miniloaders behave like filter inserters, and not like vanilla 57 | loaders: if no filters are set then no items will be moved. You must set at 58 | least one filter. 59 | 60 | ## Localization 61 | 62 | Interested in translating Miniloader to your language? Visit 63 | [Crowdin](https://crowdin.com/project/factorio-mods-localization) and the changes 64 | will be integrated into the next release. 65 | 66 | ## Known Issues 67 | 68 | * The power usage UI counts each miniloader multiple times, since it shows the 69 | power used by the inserters, not the miniloaders themselves. 70 | * Miniloader arrows don't always appear correctly in blueprints. 71 | 72 | ## Acknowledgements 73 | 74 | * Arch666Angel — for the original 2x1 loader graphics, cut down to 1x1 75 | with permission in versions through 1.5.x. 76 | * Articulating — for the original Loader Snapping. 77 | * Optera — for Loader Redux's revised and improved loader snapping code, adapted 78 | here for Miniloaders with permission. 79 | -------------------------------------------------------------------------------- /circuit.lua: -------------------------------------------------------------------------------- 1 | local event = require "lualib.event" 2 | local onwireplaced = require "lualib.onwireplaced" 3 | local util = require "lualib.util" 4 | 5 | local M = {} 6 | 7 | local function get_inserter_filters(inserter) 8 | local slots = inserter.filter_slot_count 9 | local filters = {} 10 | for i=1,slots do 11 | filters[i] = inserter.get_filter(i) 12 | end 13 | return filters 14 | end 15 | 16 | local function copy_inserter_filters(source_inserter, dest_inserter, filters) 17 | local slots = dest_inserter.filter_slot_count 18 | local inserter_filter_mode = source_inserter.inserter_filter_mode 19 | 20 | if inserter_filter_mode then 21 | dest_inserter.inserter_filter_mode = inserter_filter_mode 22 | end 23 | 24 | if not filters then 25 | filters = get_inserter_filters(source_inserter) 26 | end 27 | 28 | for i=1,slots do 29 | dest_inserter.set_filter(i, filters[i]) 30 | end 31 | end 32 | 33 | function M.sync_filters(entity) 34 | local inserters = util.get_loader_inserters(entity) 35 | local source_inserter = inserters[1] 36 | 37 | if #inserters < 2 then return end 38 | 39 | if not util.is_output_miniloader_inserter(entity) 40 | or not global.split_lane_configuration[source_inserter.unit_number] then 41 | -- sync left and right lanes 42 | copy_inserter_filters(entity, inserters[2]) 43 | end 44 | for i = 1, #inserters, 2 do 45 | copy_inserter_filters(source_inserter, inserters[i]) 46 | end 47 | source_inserter = inserters[2] 48 | for i = 4, #inserters, 2 do 49 | copy_inserter_filters(source_inserter, inserters[i]) 50 | end 51 | end 52 | 53 | local function copy_inserter_behavior(source_inserter, target) 54 | local source_behavior = source_inserter.get_or_create_control_behavior() 55 | local behavior = target.get_or_create_control_behavior() 56 | behavior.circuit_read_hand_contents = source_behavior.circuit_read_hand_contents 57 | behavior.circuit_mode_of_operation = source_behavior.circuit_mode_of_operation 58 | behavior.circuit_hand_read_mode = source_behavior.circuit_hand_read_mode 59 | behavior.circuit_set_stack_size = false 60 | behavior.circuit_stack_control_signal = {type="item"} 61 | behavior.circuit_condition = source_behavior.circuit_condition 62 | behavior.logistic_condition = source_behavior.logistic_condition 63 | behavior.connect_to_logistic_network = source_behavior.connect_to_logistic_network 64 | end 65 | 66 | function M.copy_inserter_settings(source, target) 67 | copy_inserter_filters(source, target) 68 | copy_inserter_behavior(source, target) 69 | end 70 | 71 | function M.sync_behavior(inserter) 72 | local inserters = util.get_loader_inserters(inserter) 73 | local stack_size_override = settings.global["miniloader-lock-stack-sizes"].value 74 | and 1 or inserters[1].inserter_stack_size_override 75 | for _, target in ipairs(inserters) do 76 | target.inserter_stack_size_override = stack_size_override 77 | end 78 | 79 | if #inserters < 2 then return end 80 | 81 | local source_inserter = inserters[1] 82 | if not util.is_output_miniloader_inserter(source_inserter) 83 | or not global.split_lane_configuration[source_inserter.unit_number] then 84 | -- sync left and right lanes 85 | copy_inserter_behavior(source_inserter, inserters[2]) 86 | end 87 | for i = 1, #inserters, 2 do 88 | copy_inserter_behavior(source_inserter, inserters[i]) 89 | end 90 | source_inserter = inserters[2] 91 | for i = 4, #inserters, 2 do 92 | copy_inserter_behavior(source_inserter, inserters[i]) 93 | end 94 | end 95 | 96 | local function ccds_match(ccd1, ccd2) 97 | if ccd1 == nil or ccd2 == nil then return false end 98 | return 99 | ccd1.entity == ccd2.entity and ccd1.target_entity == ccd2.target_entity 100 | or ccd1.entity == ccd2.target_entity and ccd1.target_entity == ccd2.entity 101 | end 102 | 103 | local function connected_non_partners(inserters, removed) 104 | local out = {[defines.wire_type.red] = {}, [defines.wire_type.green] = {}} 105 | for _, inserter in ipairs(inserters) do 106 | local ccds = inserter.circuit_connection_definitions 107 | local pos = inserter.position 108 | for _, ccd in ipairs(ccds) do 109 | ccd.entity = inserter 110 | local otherpos = ccd.target_entity.position 111 | if (otherpos.x ~= pos.x or otherpos.y ~= pos.y) and not ccds_match(ccd, removed) then 112 | table.insert(out[ccd.wire], ccd) 113 | end 114 | end 115 | end 116 | return out 117 | end 118 | 119 | local function count_connections_on_wire(entity, wire_type) 120 | local count = 0 121 | for _, ccd in ipairs(entity.circuit_connection_definitions) do 122 | if ccd.wire == wire_type then 123 | count = count + 1 124 | end 125 | end 126 | return count 127 | end 128 | 129 | local function partner_connections_need_sync(inserters, connections) 130 | local master_inserter = inserters[1] 131 | if not master_inserter then 132 | return false 133 | end 134 | for wire_type, wire_connections in pairs(connections) do 135 | local network = master_inserter.get_circuit_network(wire_type) 136 | if network then 137 | if not next(wire_connections) then 138 | --log("no external connections on wire color") 139 | return true 140 | end 141 | local network_id = network.network_id 142 | for i=2,#inserters do 143 | local slave_inserter = inserters[i] 144 | local slave_network = slave_inserter.get_circuit_network(wire_type) 145 | if not slave_network or slave_network.network_id ~= network_id then 146 | --log("slave connected to no or different network") 147 | return true 148 | end 149 | if count_connections_on_wire(slave_inserter, wire_type) ~= 1 then 150 | --log("slave has bad connection count") 151 | return true 152 | end 153 | end 154 | else 155 | for i=2,#inserters do 156 | local slave_inserter = inserters[i] 157 | local slave_network = slave_inserter.get_circuit_network(wire_type) 158 | if slave_network then 159 | --log("slave has network connection") 160 | return true 161 | end 162 | end 163 | end 164 | end 165 | --log("no sync needed") 166 | return false 167 | end 168 | 169 | function M.sync_partner_connections(inserter, removed) 170 | local inserters = util.get_loader_inserters(inserter) 171 | local connections = connected_non_partners(inserters, removed) 172 | 173 | if not partner_connections_need_sync(inserters, connections) then 174 | return 175 | end 176 | 177 | M.sync_behavior(inserter) 178 | local master_inserter = inserters[1] 179 | local other_miniloader_inserters = {} 180 | for wire_type, ccds in pairs(connections) do 181 | if not next(ccds) then 182 | for _, ins in ipairs(inserters) do 183 | ins.disconnect_neighbour(wire_type) 184 | end 185 | else 186 | master_inserter.disconnect_neighbour(wire_type) 187 | for _, ccd in ipairs(ccds) do 188 | master_inserter.connect_neighbour(ccd) 189 | if util.is_miniloader_inserter(ccd.target_entity) then 190 | other_miniloader_inserters[#other_miniloader_inserters+1] = ccd.target_entity 191 | end 192 | end 193 | for i=2,#inserters do 194 | local ins = inserters[i] 195 | ins.disconnect_neighbour(wire_type) 196 | ins.connect_neighbour{wire=wire_type, target_entity=master_inserter} 197 | end 198 | end 199 | end 200 | 201 | for _, other_miniloader_inserter in pairs(other_miniloader_inserters) do 202 | M.sync_partner_connections(other_miniloader_inserter) 203 | end 204 | end 205 | 206 | local control_behavior_keys = { 207 | "circuit_condition", "logistic_condition", "connect_to_logistic_network", 208 | "circuit_read_hand_contents", "circuit_mode_of_operation", "circuit_hand_read_mode", "circuit_set_stack_size", "circuit_stack_control_signal", 209 | } 210 | 211 | local function on_wire_added(ev) 212 | for _, entity in ipairs{ev.entity, ev.target_entity} do 213 | if entity.valid and util.is_miniloader_inserter(entity) then 214 | M.sync_partner_connections(entity) 215 | end 216 | end 217 | end 218 | 219 | local function on_wire_removed(ev) 220 | for _, entity in ipairs{ev.entity, ev.target_entity} do 221 | if entity.valid and util.is_miniloader_inserter(entity) then 222 | M.sync_partner_connections(entity, ev) 223 | end 224 | end 225 | end 226 | 227 | function M.on_init() 228 | onwireplaced.on_init() 229 | M.on_load() 230 | end 231 | 232 | function M.on_load() 233 | onwireplaced.on_load() 234 | event.register(onwireplaced.on_wire_added, on_wire_added) 235 | event.register(onwireplaced.on_wire_removed, on_wire_removed) 236 | end 237 | 238 | function M.on_configuration_changed() 239 | onwireplaced.on_configuration_changed() 240 | end 241 | 242 | return M 243 | -------------------------------------------------------------------------------- /compat/pickerextended.lua: -------------------------------------------------------------------------------- 1 | local util = require("lualib.util") 2 | 3 | -- compatibility with PickerExtended mod 4 | local M = {} 5 | 6 | 7 | local function on_dolly_moved(event) 8 | local entity = event.moved_entity 9 | if not util.is_miniloader_inserter(entity) then 10 | return 11 | end 12 | 13 | local old_pos = event.start_pos 14 | local new_pos = entity.position 15 | 16 | -- move inserters 17 | local partners = entity.surface.find_entities_filtered{ 18 | position = old_pos, 19 | type = "inserter", 20 | } 21 | for _, ent in ipairs(partners) do 22 | ent.teleport(new_pos) 23 | end 24 | 25 | local loader = entity.surface.find_entities_filtered{ 26 | position = old_pos, 27 | type = "loader-1x1", 28 | }[1] 29 | 30 | local new_loader = entity.surface.create_entity{ 31 | name = loader.name, 32 | position = new_pos, 33 | direction = loader.direction, 34 | force = loader.force, 35 | type = loader.loader_type, 36 | } 37 | 38 | -- move items on belt 39 | for i=1,2 do 40 | local old_tl = loader.get_transport_line(i) 41 | local new_tl = new_loader.get_transport_line(i) 42 | for j=1, #old_tl do 43 | new_tl.insert_at_back(old_tl[j]) 44 | end 45 | old_tl.clear() 46 | end 47 | 48 | loader.destroy() 49 | 50 | -- move chest 51 | local chest = entity.surface.find_entity("miniloader-target-chest", old_pos) 52 | chest.teleport(new_pos) 53 | end 54 | 55 | function M.on_load() 56 | if remote.interfaces["PickerDollies"] and remote.interfaces["PickerDollies"]["dolly_moved_entity_id"] then 57 | local on_dolly_moved_event = remote.call("PickerDollies", "dolly_moved_entity_id") 58 | script.on_event(on_dolly_moved_event, on_dolly_moved) 59 | end 60 | end 61 | 62 | return M 63 | -------------------------------------------------------------------------------- /configchange.lua: -------------------------------------------------------------------------------- 1 | local miniloader = require "lualib.miniloader" 2 | local util = require "lualib.util" 3 | 4 | local configchange = {} 5 | 6 | local version = require("version") 7 | 8 | local all_migrations = {} 9 | 10 | local function add_migration(migration) 11 | all_migrations[#all_migrations+1] = migration 12 | end 13 | 14 | local forall_miniloaders = miniloader.forall 15 | 16 | add_migration{ 17 | name = "v1_9_4_fix_mined_loaders", 18 | low = {0,0,0}, 19 | high = {1,9,4}, 20 | task = function() 21 | for _, surface in pairs(game.surfaces) do 22 | for _, inserter in pairs(surface.find_entities_filtered{type = "inserter"}) do 23 | if util.is_miniloader_inserter(inserter) then 24 | local loader_name = inserter.name:gsub("%-inserter$", "").."-loader" 25 | if not surface.find_entity(loader_name, inserter.position) then 26 | log("found miniloader-inserter without miniloader-loader at " 27 | ..serpent.line(inserter.position).." on "..surface.name) 28 | local orientation = util.orientation_from_inserters(inserter) 29 | surface.create_entity{ 30 | name = loader_name, 31 | position = inserter.position, 32 | direction = orientation.direction, 33 | force = inserter.force, 34 | type = orientation.type, 35 | create_build_effect_smoke = false, 36 | } 37 | end 38 | end 39 | end 40 | end 41 | end, 42 | } 43 | 44 | add_migration{ 45 | name = "v1_10_0_add_fake_target_chests", 46 | low = {0,0,0}, 47 | high = {1,10,0}, 48 | task = function() 49 | forall_miniloaders(function(surface, entity) 50 | surface.create_entity{ 51 | name = "miniloader-target-chest", 52 | position = entity.position, 53 | force = entity.force, 54 | } 55 | end) 56 | end, 57 | } 58 | 59 | add_migration{ 60 | name = "v1_10_0_add_boblogistics_basic_miniloader", 61 | low = {0,0,0}, 62 | high = {1,10,0}, 63 | task = function() 64 | if game.technology_prototypes["basic-miniloader"] then 65 | for _, f in pairs(game.forces) do 66 | if f.technologies["miniloader"].researched then 67 | f.technologies["basic-miniloader"].researched = true 68 | end 69 | end 70 | end 71 | end, 72 | } 73 | 74 | add_migration{ 75 | name = "v1_11_1_remove_stray_chests", 76 | low = {0,0,0}, 77 | high = {1,11,1}, 78 | task = function() 79 | for _, s in pairs(game.surfaces) do 80 | for _, chest in pairs(s.find_entities_filtered{name = "miniloader-target-chest"}) do 81 | if not next(util.find_miniloaders{surface = s, position = chest.position}) then 82 | chest.destroy() 83 | end 84 | end 85 | end 86 | end, 87 | } 88 | 89 | add_migration{ 90 | name = "v1_12_3_add_global_player_placed_blueprint", 91 | low = {0,0,0}, 92 | high = {1,12,3}, 93 | task = function() 94 | global.player_placed_blueprint = {} 95 | end, 96 | } 97 | 98 | add_migration{ 99 | name = "v1_14_3_add_global_previous_opened_blueprint_for", 100 | low = {0,0,0}, 101 | high = {1,14,3}, 102 | task = function() 103 | global.previous_opened_blueprint_for = {} 104 | end, 105 | } 106 | 107 | add_migration{ 108 | name = "v1_15_4_add_global_split_lane_configuration", 109 | low = {0,0,0}, 110 | high = {1,15,4}, 111 | task = function() 112 | global.split_lane_configuration = {} 113 | end, 114 | } 115 | 116 | function configchange.on_mod_version_changed(old) 117 | old = version.parse(old) 118 | for _, migration in ipairs(all_migrations) do 119 | if version.between(old, migration.low, migration.high) then 120 | log("running world migration "..migration.name) 121 | migration.task() 122 | end 123 | end 124 | end 125 | 126 | -- changes in other mods may affect belt speeds, and hence the required number of inserters 127 | function configchange.fix_inserter_counts() 128 | forall_miniloaders(function(surface, loader) 129 | local inserters = util.get_loader_inserters(loader) 130 | if not next(inserters) then 131 | log("Miniloader at "..loader.position.x..", "..loader.position.y.. 132 | " on surface "..surface.name.." has no inserters.") 133 | loader.destroy() 134 | return 135 | end 136 | miniloader.fixup(inserters[1]) 137 | end) 138 | end 139 | 140 | return configchange 141 | -------------------------------------------------------------------------------- /control.lua: -------------------------------------------------------------------------------- 1 | local blueprint = require("lualib.blueprint") 2 | local circuit = require("circuit") 3 | local configchange = require("configchange") 4 | local event = require("lualib.event") 5 | local miniloader = require("lualib.miniloader") 6 | local gui = require("gui") 7 | local snapping = require("snapping") 8 | local util = require("lualib.util") 9 | 10 | local compat_pickerextended = require("compat.pickerextended") 11 | 12 | local use_snapping = settings.global["miniloader-snapping"].value 13 | 14 | --[[ 15 | loader_type = "input" 16 | +------------------+ 17 | | | 18 | | P | 19 | | | 20 | | | | 21 | | | | chest dir 22 | | | | 23 | | | v 24 | | | 25 | +------------------+ 26 | D D 27 | -- 28 | loader_type = "output" 29 | +------------------+ 30 | | | 31 | | D D | 32 | | | 33 | | | | 34 | | | | chest dir 35 | | | | 36 | | | v 37 | | | 38 | +------------------+ 39 | P 40 | -- 41 | D: drop positions 42 | P: pickup position 43 | ]] 44 | 45 | local function register_bobs_blacklist() 46 | for _, interface_name in ipairs{"bobinserters", "boblogistics"} do 47 | local interface = remote.interfaces[interface_name] 48 | if interface and interface["blacklist_inserter"] then 49 | for entity_name in pairs(game.entity_prototypes) do 50 | if util.is_miniloader_inserter_name(entity_name) then 51 | remote.call(interface_name, "blacklist_inserter", entity_name) 52 | end 53 | end 54 | end 55 | end 56 | end 57 | 58 | -- Event Handlers 59 | 60 | local function on_init() 61 | global.player_placed_blueprint = {} 62 | global.previous_opened_blueprint_for = {} 63 | global.split_lane_configuration = {} 64 | circuit.on_init() 65 | compat_pickerextended.on_load() 66 | gui.on_init() 67 | register_bobs_blacklist() 68 | end 69 | 70 | local function on_load() 71 | circuit.on_load() 72 | compat_pickerextended.on_load() 73 | gui.on_load() 74 | end 75 | 76 | local function on_configuration_changed(configuration_changed_data) 77 | local mod_change = configuration_changed_data.mod_changes["miniloader"] 78 | if mod_change and mod_change.old_version and mod_change.old_version ~= mod_change.new_version then 79 | configchange.on_mod_version_changed(mod_change.old_version) 80 | circuit.on_configuration_changed() 81 | gui.on_configuration_changed() 82 | end 83 | register_bobs_blacklist() 84 | configchange.fix_inserter_counts() 85 | end 86 | 87 | local fast_replace_miniloader_state 88 | 89 | local function on_built_miniloader(entity, orientation, tags) 90 | if not orientation then 91 | orientation = {direction = util.opposite_direction(entity.direction), type = "input"} 92 | end 93 | if not tags 94 | and util.is_output_miniloader_inserter(entity) 95 | and fast_replace_miniloader_state 96 | and fast_replace_miniloader_state.tick == game.tick 97 | and fast_replace_miniloader_state.surface == entity.surface 98 | and fast_replace_miniloader_state.position.x == entity.position.x 99 | and fast_replace_miniloader_state.position.y == entity.position.y 100 | then 101 | tags = { 102 | right_lane_settings = fast_replace_miniloader_state.right_lane_settings, 103 | } 104 | fast_replace_miniloader_state = nil 105 | end 106 | return miniloader.fixup(entity, orientation, tags) 107 | end 108 | 109 | local function on_robot_built(ev) 110 | local entity = ev.created_entity 111 | if util.is_miniloader_inserter(entity) then 112 | on_built_miniloader(entity, util.orientation_from_inserters(entity), ev.tags) 113 | end 114 | end 115 | 116 | local function on_script_built(ev) 117 | local entity = ev.entity 118 | if entity and util.is_miniloader_inserter(entity) then 119 | on_built_miniloader(entity, util.orientation_from_inserters(entity)) 120 | end 121 | end 122 | 123 | local function on_script_revive(ev) 124 | local entity = ev.entity 125 | if entity and util.is_miniloader_inserter(entity) then 126 | on_built_miniloader(entity, util.orientation_from_inserters(entity), ev.tags) 127 | end 128 | end 129 | 130 | local function on_player_built(ev) 131 | local entity = ev.created_entity 132 | 133 | if util.is_miniloader_inserter(entity) then 134 | local orientation = util.orientation_from_inserters(entity) 135 | local loader = on_built_miniloader(entity, orientation, ev.tags) 136 | if use_snapping and not orientation then 137 | -- adjusts direction & loader_type 138 | snapping.snap_loader(loader) 139 | end 140 | elseif use_snapping 141 | and entity.type == "entity-ghost" 142 | and util.is_miniloader_inserter_name(entity.ghost_name) then 143 | -- remove duplicate ghosts 144 | local colocated_ghosts = entity.surface.find_entities_filtered{ 145 | position = entity.position, 146 | ghost_name = entity.ghost_name, 147 | } 148 | for _, ghost in pairs(colocated_ghosts) do 149 | if ghost ~= entity then 150 | ghost.destroy() 151 | end 152 | end 153 | if util.orientation_from_inserters(entity) == nil then 154 | snapping.snap_loader(entity) 155 | end 156 | elseif use_snapping then 157 | snapping.check_for_loaders(ev) 158 | end 159 | end 160 | 161 | local function on_rotated(ev) 162 | local entity = ev.entity 163 | if util.is_miniloader_inserter(entity) then 164 | local miniloader = util.find_miniloaders{ 165 | surface = entity.surface, 166 | position = entity.position, 167 | force = entity.force, 168 | }[1] 169 | miniloader.rotate{ by_player = game.players[ev.player_index] } 170 | util.update_inserters(miniloader) 171 | elseif util.is_miniloader(entity) then 172 | util.update_inserters(entity) 173 | elseif use_snapping then 174 | snapping.check_for_loaders(ev) 175 | end 176 | end 177 | 178 | local function on_miniloader_mined(ev) 179 | local entity = ev.entity 180 | local buffer = ev.buffer and ev.buffer.valid and ev.buffer 181 | local inserters = util.get_loader_inserters(entity) 182 | if buffer and inserters[1] then 183 | local _, item_to_place = next(inserters[1].prototype.items_to_place_this) 184 | buffer.insert{desired_count=1, name=item_to_place.name} 185 | end 186 | for i=1,#inserters do 187 | -- return items to player / robot if mined 188 | if buffer and inserters[i] ~= entity and inserters[i].held_stack.valid_for_read then 189 | buffer.insert(inserters[i].held_stack) 190 | end 191 | inserters[i].destroy() 192 | end 193 | local chest = entity.surface.find_entity("miniloader-target-chest", entity.position) 194 | if chest then 195 | chest.destroy() 196 | end 197 | end 198 | 199 | local function on_miniloader_inserter_mined(ev) 200 | local entity = ev.entity 201 | local buffer = ev.buffer and ev.buffer.valid and ev.buffer 202 | local loader = entity.surface.find_entities_filtered{ 203 | position = entity.position, 204 | type = "loader-1x1", 205 | }[1] 206 | if loader then 207 | if buffer then 208 | for i=1,2 do 209 | local tl = loader.get_transport_line(i) 210 | for j=1,math.min(#tl, 256) do 211 | buffer.insert(tl[j]) 212 | end 213 | tl.clear() 214 | end 215 | end 216 | loader.destroy() 217 | end 218 | 219 | local inserters = util.get_loader_inserters(entity) 220 | if util.is_output_miniloader_inserter(entity) 221 | and global.split_lane_configuration[entity.unit_number] then 222 | fast_replace_miniloader_state = { 223 | position = entity.position, 224 | right_lane_settings = util.capture_settings(inserters[2]), 225 | surface = entity.surface, 226 | tick = ev.tick, 227 | } 228 | global.split_lane_configuration[entity.unit_number] = nil 229 | end 230 | for i=1,#inserters do 231 | if inserters[i] ~= entity then 232 | -- return items in inserter hand to player / robot if mined 233 | if buffer and inserters[i].held_stack.valid_for_read then 234 | buffer.insert(inserters[i].held_stack) 235 | end 236 | inserters[i].destroy() 237 | end 238 | end 239 | 240 | local chest = entity.surface.find_entity("miniloader-target-chest", entity.position) 241 | if chest then 242 | chest.destroy() 243 | end 244 | end 245 | 246 | local function on_mined(ev) 247 | local entity = ev.entity 248 | if util.is_miniloader(entity) then 249 | on_miniloader_mined(ev) 250 | elseif util.is_miniloader_inserter(entity) then 251 | on_miniloader_inserter_mined(ev) 252 | end 253 | end 254 | 255 | local function on_placed_blueprint(ev, player, bp_entities) 256 | if not next(bp_entities) then return end 257 | 258 | global.player_placed_blueprint[ev.player_index] = ev.tick 259 | 260 | local surface = player.surface 261 | local bp_area = blueprint.bounding_box(bp_entities) 262 | local surface_area = util.move_box( 263 | util.rotate_box(bp_area, ev.direction), 264 | ev.position 265 | ) 266 | 267 | local blueprint_contained_miniloader = false 268 | for _, bp_entity in pairs(bp_entities) do 269 | if util.is_miniloader_inserter_name(bp_entity.name) then 270 | blueprint_contained_miniloader = true 271 | break 272 | end 273 | end 274 | 275 | if blueprint_contained_miniloader then 276 | -- remember where we have placed a blueprint so we can check for changes next tick 277 | if not global.placed_blueprint_areas then global.placed_blueprint_areas = {} end 278 | global.placed_blueprint_areas[#global.placed_blueprint_areas+1] = { 279 | surface = surface, 280 | area = surface_area, 281 | } 282 | end 283 | end 284 | 285 | -- A blueprint placed over existing miniloaders in the previous tick 286 | -- may have changed their orientation. 287 | local function check_placed_blueprints_for_miniloaders() 288 | if not global.placed_blueprint_areas or not next(global.placed_blueprint_areas) then return end 289 | for _, data in ipairs(global.placed_blueprint_areas) do 290 | local surface = data.surface 291 | local area = data.area 292 | if surface.valid then 293 | local inserter_entities = surface.find_entities_filtered{ 294 | area = area, 295 | type = "inserter", 296 | } 297 | for _, e in pairs(inserter_entities) do 298 | if util.is_miniloader_inserter(e) then 299 | miniloader.fixup(e, util.orientation_from_inserters(e)) 300 | end 301 | end 302 | end 303 | end 304 | 305 | global.placed_blueprint_areas = {} 306 | end 307 | 308 | local function on_pre_build(ev) 309 | local player_index = ev.player_index 310 | local player = game.players[player_index] 311 | local bp_entities = player.get_blueprint_entities() 312 | if bp_entities then 313 | return on_placed_blueprint(ev, player, bp_entities) 314 | end 315 | end 316 | 317 | local function on_pre_player_mined_item(ev) 318 | local entity = ev.entity 319 | if entity.name == "entity-ghost" and entity.tags and entity.tags.right_lane_settings then 320 | fast_replace_miniloader_state = { 321 | position = entity.position, 322 | right_lane_settings = entity.tags.right_lane_settings, 323 | surface = entity.surface, 324 | tick = ev.tick, 325 | } 326 | end 327 | end 328 | 329 | local function on_player_mined_entity(ev) 330 | on_mined(ev) 331 | end 332 | 333 | local function on_entity_settings_pasted(ev) 334 | local src = ev.source 335 | local dst = ev.destination 336 | if util.is_miniloader_inserter(src) and util.is_miniloader_inserter(dst) then 337 | local src_loader = src.surface.find_entities_filtered{type="loader-1x1",position=src.position}[1] 338 | local dst_loader = dst.surface.find_entities_filtered{type="loader-1x1",position=dst.position}[1] 339 | if src_loader and dst_loader then 340 | dst_loader.loader_type = src_loader.loader_type 341 | util.update_inserters(dst_loader) 342 | end 343 | if util.is_output_miniloader_inserter(src) then 344 | local right_src = util.get_loader_inserters(src)[2] 345 | local right_dst = util.get_loader_inserters(dst)[2] 346 | if right_src and right_dst then 347 | global.split_lane_configuration[dst.unit_number] = global.split_lane_configuration[src.unit_number] 348 | circuit.copy_inserter_settings(right_src, right_dst) 349 | end 350 | end 351 | circuit.sync_behavior(dst) 352 | circuit.sync_filters(dst) 353 | end 354 | end 355 | 356 | local function on_gui_closed(event) 357 | local player = game.get_player(event.player_index) 358 | if event.gui_type == defines.gui_type.item 359 | and event.item 360 | and event.item.is_blueprint 361 | and event.item.is_blueprint_setup() 362 | and player.cursor_stack 363 | and player.cursor_stack.valid_for_read 364 | and player.cursor_stack.is_blueprint 365 | and not player.cursor_stack.is_blueprint_setup() 366 | then 367 | global.previous_opened_blueprint_for[event.player_index] = { 368 | blueprint = event.item, 369 | tick = event.tick, 370 | } 371 | else 372 | global.previous_opened_blueprint_for[event.player_index] = nil 373 | end 374 | end 375 | 376 | local function on_setup_blueprint(ev) 377 | local bp = blueprint.get_blueprint_to_setup(ev.player_index) 378 | if not (bp and bp.valid_for_read) then return end 379 | blueprint.filter_miniloaders(bp, ev.surface) 380 | end 381 | 382 | local function on_marked_for_deconstruction(ev) 383 | local entity = ev.entity 384 | if not (util.is_miniloader(entity) or util.is_miniloader_inserter(entity)) then return end 385 | for _, ent in ipairs(entity.surface.find_entities_filtered{position=entity.position}) do 386 | -- order_deconstruction() causes event handlers to be fired which may invalidate entities 387 | if ent.valid and (util.is_miniloader(ent) or util.is_miniloader_inserter(ent)) then 388 | if not ent.to_be_deconstructed(ent.force) then 389 | ent.order_deconstruction(ent.force) 390 | end 391 | end 392 | end 393 | end 394 | 395 | local function on_canceled_deconstruction(ev) 396 | local entity = ev.entity 397 | for _, ent in ipairs(entity.surface.find_entities_filtered{position=entity.position}) do 398 | if util.is_miniloader(ent) or util.is_miniloader_inserter(ent) then 399 | if ent.to_be_deconstructed(ent.force) then 400 | ent.cancel_deconstruction(ent.force) 401 | end 402 | end 403 | end 404 | end 405 | 406 | local function on_marked_for_upgrade(ev) 407 | local entity = ev.entity 408 | if not util.is_miniloader_inserter(entity) then return end 409 | local main_inserter = entity.surface.find_entity(entity.name, entity.position) 410 | if entity == main_inserter then return end 411 | local force = ev.player_index and game.get_player(ev.player_index).force or entity.force 412 | entity.cancel_upgrade(force) 413 | end 414 | 415 | -- lifecycle events 416 | 417 | script.on_init(on_init) 418 | script.on_load(on_load) 419 | script.on_configuration_changed(on_configuration_changed) 420 | 421 | -- entity events 422 | 423 | event.register(defines.events.on_built_entity, on_player_built) 424 | event.register(defines.events.on_robot_built_entity, on_robot_built) 425 | event.register(defines.events.on_player_rotated_entity, on_rotated) 426 | 427 | event.register(defines.events.on_pre_player_mined_item, on_pre_player_mined_item) 428 | event.register(defines.events.on_player_mined_entity, on_player_mined_entity) 429 | event.register(defines.events.on_robot_mined_entity, on_mined) 430 | event.register(defines.events.on_entity_died, on_mined) 431 | event.register(defines.events.script_raised_built, on_script_built) 432 | event.register(defines.events.script_raised_revive, on_script_revive) 433 | event.register(defines.events.script_raised_destroy, on_mined) 434 | 435 | event.register(defines.events.on_entity_settings_pasted, on_entity_settings_pasted) 436 | event.register(defines.events.on_pre_build, on_pre_build) 437 | 438 | event.register(defines.events.on_player_setup_blueprint, on_setup_blueprint) 439 | event.register(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction) 440 | event.register(defines.events.on_canceled_deconstruction, on_canceled_deconstruction) 441 | 442 | event.register(defines.events.on_marked_for_upgrade, on_marked_for_upgrade) 443 | 444 | event.register(defines.events.on_gui_closed, on_gui_closed) 445 | 446 | event.register(defines.events.on_runtime_mod_setting_changed, function(ev) 447 | if ev.setting == "miniloader-snapping" then 448 | use_snapping = settings.global["miniloader-snapping"].value 449 | elseif ev.setting == "miniloader-lock-stack-sizes" then 450 | local size = settings.global["miniloader-lock-stack-sizes"].value and 1 or 0 451 | miniloader.forall(function(surface, miniloader) 452 | for _, inserter in pairs(util.get_loader_inserters(miniloader)) do 453 | inserter.inserter_stack_size_override = size 454 | end 455 | end) 456 | end 457 | end) 458 | 459 | event.register(defines.events.on_tick, check_placed_blueprints_for_miniloaders) 460 | -------------------------------------------------------------------------------- /data-updates.lua: -------------------------------------------------------------------------------- 1 | -- boblogistics does some late changes in the data-updates phase, so we need to react to them here 2 | 3 | local function update(prefix) 4 | local loader = data.raw["loader-1x1"][prefix .. "miniloader-loader"] 5 | local loader_item = data.raw["item"][prefix .. "miniloader"] 6 | local filter_loader = data.raw["loader-1x1"][prefix .. "filter-miniloader-loader"] 7 | local filter_loader_item = data.raw["item"][prefix .. "filter-miniloader"] 8 | prefix = string.gsub(prefix, "^ub%-", "") 9 | local base_underground = data.raw["underground-belt"][prefix .. "underground-belt"] 10 | local base_underground_item = data.raw["item"][prefix .. "underground-belt"] 11 | 12 | if loader then loader.speed = base_underground.speed end 13 | if loader_item then loader_item.subgroup = base_underground_item.subgroup end 14 | if filter_loader then filter_loader.speed = base_underground.speed end 15 | if filter_loader_item then filter_loader_item.subgroup = base_underground_item.subgroup end 16 | end 17 | 18 | update("basic-") 19 | update("") 20 | update("fast-") 21 | update("express-") 22 | 23 | if data.raw["item"]["turbo-miniloader"] then 24 | update("turbo-") 25 | end 26 | if data.raw["item"]["ultimate-miniloader"] then 27 | update("ultimate-") 28 | end 29 | 30 | -- catch belt speed changes made by other mods in data stage 31 | for name, ug in pairs(data.raw["underground-belt"]) do 32 | local prefix = name:match("(.*)%-underground%-belt") 33 | local miniloader = prefix and data.raw["loader-1x1"][prefix .. "-miniloader"] 34 | if miniloader then 35 | miniloader.speed = ug.speed 36 | end 37 | end 38 | -------------------------------------------------------------------------------- /data.lua: -------------------------------------------------------------------------------- 1 | local entities = require "prototypes.entities" 2 | local items = require "prototypes.items" 3 | local recipes = require "prototypes.recipes" 4 | local technologies = require "prototypes.technologies" 5 | local templates = require "prototypes.templates" 6 | 7 | local function create_miniloader(prefix, next_prefix, tech_prereqs, tint, base_underground_name) 8 | base_underground_name = base_underground_name or (prefix .. "underground-belt") 9 | entities.create_loaders(prefix, base_underground_name, tint) 10 | entities.create_inserters(prefix, next_prefix, base_underground_name, tint) 11 | items.create_items(prefix, base_underground_name, tint) 12 | recipes.create_recipes(prefix) 13 | technologies.create_technology(prefix, tech_prereqs, tint) 14 | end 15 | 16 | for prefix, args in pairs(templates) do 17 | create_miniloader(prefix, args.next_prefix, args.prerequisite_techs, args.tint, args.base_underground_name) 18 | end 19 | 20 | -- chute 21 | if settings.startup["miniloader-enable-chute"].value then 22 | local standard_enabled = settings.startup["miniloader-enable-standard"].value 23 | settings.startup["miniloader-enable-standard"].value = true 24 | create_miniloader("chute-", "", {"logistics"}, util.color("808080D1"), "underground-belt") 25 | settings.startup["miniloader-enable-standard"].value = standard_enabled 26 | 27 | data.raw.technology["chute-miniloader"] = nil 28 | data.raw.recipe["chute-miniloader"].enabled = true 29 | data.raw["loader-1x1"]["chute-miniloader-loader"].speed = data.raw["loader-1x1"]["chute-miniloader-loader"].speed / 4 30 | local inserter = data.raw.inserter["chute-miniloader-inserter"] 31 | inserter.localised_description[5] = 32 | math.floor(data.raw["loader-1x1"]["chute-miniloader-loader"].speed * 480 * 100 + 0.5) / 100 33 | inserter.rotation_speed = data.raw.inserter["chute-miniloader-inserter"].rotation_speed / 4 34 | inserter.energy_source = {type="void"} 35 | inserter.energy_per_movement = ".0000001J" 36 | inserter.energy_per_rotation = ".0000001J" 37 | inserter.circuit_wire_max_distance = 0 38 | if not data.raw.inserter[inserter.next_upgrade] then 39 | inserter.next_upgrade = nil 40 | end 41 | 42 | data.raw.item["chute-filter-miniloader"] = nil 43 | data.raw.recipe["chute-filter-miniloader"] = nil 44 | data.raw["loader-1x1"]["chute-filter-miniloader-loader"] = nil 45 | data.raw.inserter["chute-filter-miniloader-inserter"] = nil 46 | end 47 | -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-filter-inserter-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-filter-inserter-base.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-filter-structure-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-filter-structure-base.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-filter-structure-front-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-filter-structure-front-patch.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-inserter-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-inserter-base.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-structure-back-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-structure-back-patch.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-structure-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-structure-base.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-structure-front-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-structure-front-patch.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-structure-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-structure-mask.png -------------------------------------------------------------------------------- /graphics/entity/hr-miniloader-structure-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/hr-miniloader-structure-shadow.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-filter-inserter-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-filter-inserter-base.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-filter-structure-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-filter-structure-base.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-filter-structure-front-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-filter-structure-front-patch.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-inserter-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-inserter-base.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-structure-back-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-structure-back-patch.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-structure-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-structure-base.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-structure-front-patch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-structure-front-patch.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-structure-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-structure-mask.png -------------------------------------------------------------------------------- /graphics/entity/miniloader-structure-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/entity/miniloader-structure-shadow.png -------------------------------------------------------------------------------- /graphics/item/filter-icon-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/item/filter-icon-base.png -------------------------------------------------------------------------------- /graphics/item/icon-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/item/icon-base.png -------------------------------------------------------------------------------- /graphics/item/icon-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/item/icon-mask.png -------------------------------------------------------------------------------- /graphics/technology/technology-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/technology/technology-base.png -------------------------------------------------------------------------------- /graphics/technology/technology-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/graphics/technology/technology-mask.png -------------------------------------------------------------------------------- /gui.lua: -------------------------------------------------------------------------------- 1 | local circuit = require "circuit" 2 | local event = require "lualib.event" 3 | local ontick = require "lualib.ontick" 4 | local util = require "lualib.util" 5 | 6 | -- how often to poll ControlBehavior settings when a miniloader-inserter GUI is open 7 | local POLL_INTERVAL = 15 8 | 9 | local function create_lane_swap_gui(parent, entity, switch_state) 10 | if parent.miniloader_lane_swap then 11 | parent.miniloader_lane_swap.destroy() 12 | end 13 | local frame = parent.add{ 14 | type = "frame", 15 | name = "miniloader_lane_swap", 16 | direction = "horizontal", 17 | anchor = { 18 | gui = defines.relative_gui_type.inserter_gui, 19 | position = defines.relative_gui_position.top, 20 | }, 21 | } 22 | local inner_frame = frame.add{ 23 | type = "frame", 24 | name = "content", 25 | style = "inside_shallow_frame_with_padding", 26 | } 27 | inner_frame.style.horizontally_stretchable = false 28 | local flow = inner_frame.add{ 29 | type = "flow", 30 | direction = "horizontal", 31 | } 32 | flow.style.horizontal_spacing = 20 33 | flow.add{ 34 | type = "checkbox", 35 | name = "miniloader_split_lane_checkbox", 36 | caption = {"miniloader-gui.split-lane-configuration"}, 37 | state = switch_state ~= "none", 38 | } 39 | flow.add{ 40 | type = "switch", 41 | name = "miniloader_lane_switch", 42 | allow_none_state = true, 43 | left_label_caption = {"gui-splitter.left"}, 44 | right_label_caption = {"gui-splitter.right"}, 45 | switch_state = switch_state, 46 | } 47 | return frame 48 | end 49 | 50 | local monitored_entities 51 | 52 | local function should_monitor_entity(entity) 53 | return util.is_miniloader_inserter(entity) 54 | end 55 | 56 | local function monitor_open_guis(_) 57 | for k, entity in pairs(monitored_entities) do 58 | if entity.valid then 59 | circuit.sync_filters(entity) 60 | circuit.sync_behavior(entity) 61 | else 62 | monitored_entities[k] = nil 63 | end 64 | end 65 | if not next(monitored_entities) then 66 | ontick.unregister(monitor_open_guis) 67 | end 68 | end 69 | 70 | local opening_filter_gui = false 71 | 72 | local function on_gui_opened(ev) 73 | local entity = ev.entity 74 | if not entity or not should_monitor_entity(entity) then 75 | return 76 | end 77 | monitored_entities[ev.player_index] = entity 78 | ontick.register(monitor_open_guis, POLL_INTERVAL) 79 | 80 | if util.is_output_miniloader_inserter(entity) then 81 | local player = game.get_player(ev.player_index) 82 | local relative = player.gui.relative 83 | local inserters = util.get_loader_inserters(entity) 84 | local switch_state = (entity == inserters[2]) and "right" 85 | or (global.split_lane_configuration[entity.unit_number]) and "left" 86 | or "none" 87 | create_lane_swap_gui(relative, entity, switch_state) 88 | end 89 | end 90 | 91 | local function on_gui_closed(ev) 92 | local entity = ev.entity 93 | 94 | if not entity or not should_monitor_entity(entity) then 95 | return 96 | end 97 | 98 | circuit.sync_behavior(entity) 99 | circuit.sync_filters(entity) 100 | monitored_entities[ev.player_index] = nil 101 | 102 | local player = game.get_player(ev.player_index) 103 | if player.gui.relative.miniloader_lane_swap then 104 | player.gui.relative.miniloader_lane_swap.destroy() 105 | end 106 | end 107 | 108 | local function on_gui_checked_state_changed(ev) 109 | local element = ev.element 110 | if element.name ~= "miniloader_split_lane_checkbox" then return end 111 | local player = game.get_player(ev.player_index) 112 | if player.opened_gui_type ~= defines.gui_type.entity then return end 113 | local entity = player.opened 114 | if not util.is_output_miniloader_inserter(entity) then return end 115 | 116 | local inserters = util.get_loader_inserters(entity) 117 | local main_inserter = inserters[1] 118 | global.split_lane_configuration[main_inserter.unit_number] = element.state and true or nil 119 | element.parent.miniloader_lane_switch.switch_state = element.state and "left" or "none" 120 | player.opened = main_inserter 121 | end 122 | 123 | local function on_gui_switch_state_changed(ev) 124 | local element = ev.element 125 | if element.name ~= "miniloader_lane_switch" then return end 126 | local player = game.get_player(ev.player_index) 127 | if player.opened_gui_type ~= defines.gui_type.entity then return end 128 | local entity = player.opened 129 | if not util.is_output_miniloader_inserter(entity) then return end 130 | 131 | local inserters = util.get_loader_inserters(entity) 132 | local main_inserter = inserters[1] 133 | global.split_lane_configuration[main_inserter.unit_number] = element.switch_state ~= "none" and true or nil 134 | element.parent.miniloader_split_lane_checkbox.state = element.switch_state ~= "none" 135 | player.opened = element.switch_state == "right" and inserters[2] or inserters[1] 136 | end 137 | 138 | local M = {} 139 | 140 | function M.on_init() 141 | global.gui = { 142 | monitored_entities = {}, 143 | } 144 | M.on_load() 145 | end 146 | 147 | function M.on_load() 148 | if not global.gui then 149 | return -- expect on_configuration_changed 150 | end 151 | monitored_entities = global.gui.monitored_entities 152 | if next(monitored_entities) then 153 | ontick.register(monitor_open_guis, POLL_INTERVAL) 154 | end 155 | event.register(defines.events.on_gui_opened, on_gui_opened) 156 | event.register(defines.events.on_gui_closed, on_gui_closed) 157 | event.register(defines.events.on_gui_checked_state_changed, on_gui_checked_state_changed) 158 | event.register(defines.events.on_gui_switch_state_changed, on_gui_switch_state_changed) 159 | end 160 | 161 | function M.on_configuration_changed() 162 | if not global.gui then 163 | global.gui = { 164 | monitored_entities = {}, 165 | } 166 | end 167 | for _, player in pairs(game.players) do 168 | if player.gui.relative.miniloader_lane_swap then 169 | player.opened = nil 170 | player.gui.relative.miniloader_lane_swap.destroy() 171 | end 172 | end 173 | M.on_load() 174 | end 175 | 176 | return M 177 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/icon.png -------------------------------------------------------------------------------- /icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/icon2.png -------------------------------------------------------------------------------- /icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/icon3.png -------------------------------------------------------------------------------- /info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "miniloader", 3 | "version": "1.15.7", 4 | "factorio_version": "1.1", 5 | "title": "Miniloader", 6 | "author": "Therax", 7 | "homepage": "https://forums.factorio.com/viewtopic.php?f=93&t=54343", 8 | "description": "Compact and UPS-friendly 1x1 loaders. Works with train cargo wagons, circuits, filters, and Bob's faster belts.", 9 | "dependencies": [ 10 | "(?) bobinserters >= 0.17.1", 11 | "? boblogistics >= 0.17.1", 12 | "? FactorioExtended-Plus-Transport >= 0.1.5", 13 | "? Krastorio2 >= 0.9.0", 14 | "? omnimatter_energy >= 3.1.0", 15 | "? RandomFactorioThings >= 1.0.0", 16 | "? UltimateBelts >= 0.16.4", 17 | "? UltimateBelts_Owoshima_And_Pankeko-Mod >= 0.16.4", 18 | "? space-exploration >= 0.1.95", 19 | "(?) SchallBeltConfiguration" 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /locale/ca/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Rampa 3 | basic-miniloader=Carregador bàsic 4 | miniloader=Carregador 5 | fast-miniloader=Carregador ràpid 6 | express-miniloader=Carregador molt ràpid 7 | turbo-miniloader=Carregador turbo 8 | ultimate-miniloader=Carregador definitiu 9 | rapid-mk1-miniloader=Carregador àgil Mk1 10 | rapid-mk2-miniloader=Carregador àgil Mk2 11 | ub-ultra-fast-miniloader=Carregador ultra ràpid 12 | ub-extreme-fast-miniloader=Carregador extremadament ràpid 13 | ub-ultra-express-miniloader=Carregador ultra exprés 14 | ub-extreme-express-miniloader=Carregador extremadament exprés 15 | ub-ultimate-miniloader=Carregador definitiu 16 | expedited-miniloader=Carregador accelerat 17 | space-miniloader=Carregador espacial 18 | deep-space-miniloader=Carregador de l'espai exterior 19 | k-miniloader=Carregador superior 20 | kr-advanced-miniloader=Carregador avançat 21 | kr-superior-miniloader=Carregador superior 22 | nuclear-miniloader=Carregador nuclear 23 | plutonium-miniloader=Carregador de plutoni 24 | 25 | basic-filter-miniloader=Carregador bàsic amb filtre 26 | filter-miniloader=Carregador amb filtre 27 | fast-filter-miniloader=Carregador ràpid amb filtre 28 | express-filter-miniloader=Carregador molt ràpid amb filtre 29 | turbo-filter-miniloader=Carregador turbo amb filtre 30 | ultimate-filter-miniloader=Carregador definitiu amb filtre 31 | rapid-mk1-filter-miniloader=Carregador àgil amb filtre Mk1 32 | rapid-mk2-filter-miniloader=Carregador àgil amb filtre Mk2 33 | ub-ultra-fast-filter-miniloader=Carregador ultra ràpid amb filtre 34 | ub-extreme-fast-filter-miniloader=Carregador extremadament ràpid amb filtre 35 | ub-ultra-express-filter-miniloader=Carregador ultra exprés amb filtre 36 | ub-extreme-express-filter-miniloader=Carregador extremadament exprés amb filtre 37 | ub-ultimate-filter-miniloader=Carregador definitiu amb filtre 38 | expedited-filter-miniloader=Carregador accelerat 39 | space-filter-miniloader=Carregador espacial amb filtre 40 | deep-space-filter-miniloader=Carregador amb filtre de l'espai exterior 41 | k-filter-miniloader=Carregador superior amb filtre 42 | kr-advanced-filter-miniloader=Carregador avançat amb filtre 43 | kr-superior-filter-miniloader=Carregador superior amb filtre 44 | nuclear-filter-miniloader=Carregador nuclear amb filtre 45 | plutonium-filter-miniloader=Carregador de plutoni amb filtre 46 | 47 | [technology-name] 48 | basic-miniloader=Carregador bàsic 49 | miniloader=Carregador 50 | fast-miniloader=Carregador ràpid 51 | express-miniloader=Carregador molt ràpid 52 | turbo-miniloader=Carregador turbo 53 | ultimate-miniloader=Carregador definitiu 54 | rapid-mk1-miniloader=Carregador àgil Mk1 55 | rapid-mk2-miniloader=Carregador àgil Mk2 56 | ub-ultra-fast-miniloader=Carregador ultra ràpid 57 | ub-extreme-fast-miniloader=Carregador extremadament ràpid 58 | ub-ultra-express-miniloader=Carregador ultra exprés 59 | ub-extreme-express-miniloader=Carregador extremadament exprés 60 | ub-ultimate-miniloader=Carregador definitiu 61 | expedited-miniloader=Carregador accelerat 62 | space-miniloader=Carregador espacial 63 | deep-space-miniloader=Carregador de l'espai exterior 64 | k-miniloader=Carregador superior 65 | kr-advanced-miniloader=Carregador avançat 66 | kr-superior-miniloader=Carregador superior 67 | nuclear-miniloader=Carregador nuclear 68 | plutonium-miniloader=Carregador de plutoni 69 | 70 | [technology-description] 71 | basic-miniloader=Carregador bàsic 72 | miniloader=Carregador 73 | fast-miniloader=Carregador ràpid 74 | express-miniloader=Carregador molt ràpid 75 | turbo-miniloader=Carregador turbo 76 | ultimate-miniloader=Carregador definitiu 77 | rapid-mk1-miniloader=Carregador àgil Mk1 78 | rapid-mk2-miniloader=Carregador àgil Mk2 79 | ub-ultra-fast-miniloader=Carregador ultra ràpid 80 | ub-extreme-fast-miniloader=Carregador extremadament ràpid 81 | ub-ultra-express-miniloader=Carregador ultra exprés 82 | ub-extreme-express-miniloader=Carregador extremadament exprés 83 | ub-ultimate-miniloader=Carregador definitiu 84 | expedited-miniloader=Carregador accelerat 85 | space-miniloader=Carregador espacial 86 | deep-space-miniloader=Carregador de l'espai exterior 87 | k-miniloader=Carregador superior 88 | kr-advanced-miniloader=Carregador avançat 89 | kr-superior-miniloader=Carregador superior 90 | nuclear-miniloader=Carregador avançat, potenciat amb urani 91 | plutonium-miniloader=Carregador encara més avançat, potenciat amb plutoni 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Activa els carregadors estàndard 95 | miniloader-enable-filter=Activa els carregadors amb filtre 96 | miniloader-enable-chute=Activa la rampa 97 | miniloader-energy-usage=Els carregadors utilitzen energia 98 | miniloader-snapping=Ajusta carregadors 99 | miniloader-double-recipes=Duplicar receptes 100 | miniloader-lock-stack-sizes=Bloqueja la mida de la pila 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Quan s'activa, els carregadors s'han de connectar a la xarxa elèctrica. 104 | miniloader-snapping=Ajusta els carregadors a les cintes transportadores quan es construeixen o es roten cintes transportadores adjacents. 105 | miniloader-double-recipes=Dobla el cost i resultat de les receptes, per consumir les cintes transportadores subterrànies per parelles. 106 | miniloader-lock-stack-sizes=Quan s'activa, els carregadors sempre mouran els elements d’un en un. Desactivar-ho permet utilitzar mides de piles il·limitades. Això reduirà el consum d’UPS, però farà menys consistent el nombre d'elements moguts. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Configuració de carril dividit 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/cs/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Chute 3 | basic-miniloader=Základní malý nakladač 4 | miniloader=Malý nakladač 5 | fast-miniloader=Rychlý malý nakladač 6 | express-miniloader=Expresní malý nakladač 7 | turbo-miniloader=Turbo malý nakladač 8 | ultimate-miniloader=Ultimátní malý nakladač 9 | rapid-mk1-miniloader=Rapidní malý nakladač MK1 10 | rapid-mk2-miniloader=Rapidní malý nakladač MK2 11 | ub-ultra-fast-miniloader=Ultra rychlý malý nakladač 12 | ub-extreme-fast-miniloader=Extrémně rychlý malý nakladač 13 | ub-ultra-express-miniloader=Ultra expresní malý nakladač 14 | ub-extreme-express-miniloader=Extrémně expresní malý nakladač 15 | ub-ultimate-miniloader=Ultimátní malý nakladač 16 | expedited-miniloader=Omezený malý nakladač 17 | space-miniloader=Vesmírný malý nakladač 18 | deep-space-miniloader=Hluboký vesmír malý nakladač 19 | k-miniloader=Vynikající malý nakladač 20 | kr-advanced-miniloader=Vylepšený malý nakladač 21 | kr-superior-miniloader=Vynikající malý nakladač 22 | nuclear-miniloader=Jaderný malý nakladač 23 | plutonium-miniloader=Plutoniový malý nakladač 24 | 25 | basic-filter-miniloader=Základní malý nakladač s filtrem 26 | filter-miniloader=Malý nakladač s filtrem 27 | fast-filter-miniloader=Rychlý malý nakladač s filtrem 28 | express-filter-miniloader=Expresní malý nakladač s filtrem 29 | turbo-filter-miniloader=Turbo malý nakladač s filtrem 30 | ultimate-filter-miniloader=Ultimátní malý nakladač s filtrem 31 | rapid-mk1-filter-miniloader=Rapidní malý nakladač s filtrem MK1 32 | rapid-mk2-filter-miniloader=Rapidní malý nakladač s filtrem MK2 33 | ub-ultra-fast-filter-miniloader=Ultra rychlý malý nakladač s filtrem 34 | ub-extreme-fast-filter-miniloader=Extrémně rychlý malý nakladač s filtrem 35 | ub-ultra-express-filter-miniloader=Ultra expresní malý nakladač s filtrem 36 | ub-extreme-express-filter-miniloader=Extrémně expresní malý nakladač s filtrem 37 | ub-ultimate-filter-miniloader=Ultimátní malý nakladač s filtrem 38 | expedited-filter-miniloader=Malý nakladač s omezeným filtrem 39 | space-filter-miniloader=Vesmírný malý nakladač s filtrem 40 | deep-space-filter-miniloader=Hluboký vesmír malý nakladač s filtrem 41 | k-filter-miniloader=Vynikající malý nakladač s filtrem 42 | kr-advanced-filter-miniloader=Vylepšený malý nakladač s filtrem 43 | kr-superior-filter-miniloader=Vynikající malý nakladač s filtrem 44 | nuclear-filter-miniloader=Jaderný malý nakladač s filtrem 45 | plutonium-filter-miniloader=Plutoniový malý nakladač s filtrem 46 | 47 | [technology-name] 48 | basic-miniloader=Základní malý nakladač 49 | miniloader=Malý nakladač 50 | fast-miniloader=Rychlý malý nakladač 51 | express-miniloader=Expresní malý nakladač 52 | turbo-miniloader=Turbo malý nakladač 53 | ultimate-miniloader=Ultimátní malý nakladač 54 | rapid-mk1-miniloader=Rapidní malý nakladač MK1 55 | rapid-mk2-miniloader=Rapidní malý nakladač MK2 56 | ub-ultra-fast-miniloader=Ultra rychlý malý nakladač 57 | ub-extreme-fast-miniloader=Extrémně rychlý malý nakladač 58 | ub-ultra-express-miniloader=Ultra expresní malý nakladač 59 | ub-extreme-express-miniloader=Extrémně expresní malý nakladač 60 | ub-ultimate-miniloader=Ultimátní malý nakladač 61 | expedited-miniloader=Malý nakladač s omezeným filtrem 62 | space-miniloader=Vesmírný malý nakladač 63 | deep-space-miniloader=Hluboký vesmír malý nakladač 64 | k-miniloader=Vynikající malý nakladač 65 | kr-advanced-miniloader=Vylepšený malý nakladač 66 | kr-superior-miniloader=Vynikající malý nakladač 67 | nuclear-miniloader=Jaderný malý nakladač 68 | plutonium-miniloader=Plutoniový malý nakladač 69 | 70 | [technology-description] 71 | basic-miniloader=Základní malý nakladač 72 | miniloader=Malý nakladač 73 | fast-miniloader=Rychlý malý nakladač 74 | express-miniloader=Expresní malý nakladač 75 | turbo-miniloader=Turbo malý nakladač 76 | ultimate-miniloader=Ultimátní malý nakladač 77 | rapid-mk1-miniloader=Rapidní malý nakladač MK1 78 | rapid-mk2-miniloader=Rapidní malý nakladač MK2 79 | ub-ultra-fast-miniloader=Ultra rychlý malý nakladač 80 | ub-extreme-fast-miniloader=Extrémně rychlý malý nakladač 81 | ub-ultra-express-miniloader=Ultra expresní malý nakladač 82 | ub-extreme-express-miniloader=Extrémně expresní malý nakladač 83 | ub-ultimate-miniloader=Ultimátní malý nakladač 84 | expedited-miniloader=Omezený malý nakladač 85 | space-miniloader=Vesmírný malý nakladač 86 | deep-space-miniloader=Hluboký vesmír malý nakladač 87 | k-miniloader=Vynikající malý nakladač 88 | kr-advanced-miniloader=Vylepšený malý nakladač 89 | kr-superior-miniloader=Vynikající malý nakladač 90 | nuclear-miniloader=Vylepšený malý překladač posílený uranem 91 | plutonium-miniloader=Ještě pokročilejší malý překladač vylepšený plutoniem 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Povolit standardní malé překladače 95 | miniloader-enable-filter=Povolit malé překladače s filtrem 96 | miniloader-enable-chute=Povolit chute 97 | miniloader-energy-usage=Malé překladače vyžadují energii 98 | miniloader-snapping=Přichytit malé překladače 99 | miniloader-double-recipes=Dvojité recepty 100 | miniloader-lock-stack-sizes=Uzamknout velikost zásobníku 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Pokud je nastaveno, malé překladače musí být napojené na elektrickou síť. 104 | miniloader-snapping=Připnout malé překladače k pásům když jsou postavený nebo blízké pásy otáčený. 105 | miniloader-double-recipes=Dvojnásobné náklady a výsledky receptů ke spotřebě podzemních pásů ve dvojicích. 106 | miniloader-lock-stack-sizes=Pokud je "TRUE", malé nakladače vždy přesouvají předměty najednou. Nastavení na hodnotu "FALSE" umožňuje neomezený počet zásobníků. Tím se sníží spotřeba UPS ale sníží se rychlost pohybu předmětu po nich. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Nastavení rozdělení pruhu 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/de/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Beladerampe 3 | basic-miniloader=Einfacher Minibelader 4 | miniloader=Minibelader 5 | fast-miniloader=Schneller Minibelader 6 | express-miniloader=Express-Minibelader 7 | turbo-miniloader=Turbo-Minibelader 8 | ultimate-miniloader=Ultimativer Minibelader 9 | rapid-mk1-miniloader=Schneller Minibelader Mk1 10 | rapid-mk2-miniloader=Schneller Minibelader Mk2 11 | ub-ultra-fast-miniloader=Ultraschneller Minibelader 12 | ub-extreme-fast-miniloader=Extrem schneller Minibelader 13 | ub-ultra-express-miniloader=Ultra Express Minibelader 14 | ub-extreme-express-miniloader=Extrem Express Minibelader 15 | ub-ultimate-miniloader=Ultimativer Minibelader 16 | expedited-miniloader=Beschleunigter Minibelader 17 | space-miniloader=Weltraum-Minibelader 18 | deep-space-miniloader=Tiefraum Minibelader 19 | k-miniloader=Überlegener Minibelader 20 | kr-advanced-miniloader=Fortgeschrittener Minibelader 21 | kr-superior-miniloader=Überlegener Minibelader 22 | nuclear-miniloader=Nuklear Minibelader 23 | plutonium-miniloader=Plutonium Minibelader 24 | 25 | basic-filter-miniloader=Einfacher filternder Minibelader 26 | filter-miniloader=Filternder Minibelader 27 | fast-filter-miniloader=Schneller filternder Minibelader 28 | express-filter-miniloader=Filternder Express-Minibelader 29 | turbo-filter-miniloader=Filternder Turbo-Minibelader 30 | ultimate-filter-miniloader=Ultimativer filternder Minibelader 31 | rapid-mk1-filter-miniloader=Schneller filternder Minibelader Mk 1 32 | rapid-mk2-filter-miniloader=Schneller filternder Minibelader Mk 2 33 | ub-ultra-fast-filter-miniloader=Ultraschneller filternder Minibelader Mk 1 34 | ub-extreme-fast-filter-miniloader=Extremschneller filternder Minibelader Mk 1 35 | ub-ultra-express-filter-miniloader=Ultra Express filternder Minibelader 36 | ub-extreme-express-filter-miniloader=Extremer filternder Express-Minibelader 37 | ub-ultimate-filter-miniloader=Ultimativer filternder Minibelader 38 | expedited-filter-miniloader=Filternder Express-Minibelader 39 | space-filter-miniloader=Filternder Weltraum-Minibelader 40 | deep-space-filter-miniloader=Tiefraum filternder Minibelader 41 | k-filter-miniloader=Filternder Turbo-Minibelader 42 | kr-advanced-filter-miniloader=Fortgeschrittener filternder Minibelader 43 | kr-superior-filter-miniloader=Filternder Turbo-Minibelader 44 | nuclear-filter-miniloader=Nuklearer filternder Minibelader 45 | plutonium-filter-miniloader=Filternder Plutonium-Minibelader 46 | 47 | [technology-name] 48 | basic-miniloader=Einfacher Minibelader 49 | miniloader=Minibelader 50 | fast-miniloader=Schneller Minibelader 51 | express-miniloader=Express-Minibelader 52 | turbo-miniloader=Turbo-Minibelader 53 | ultimate-miniloader=Ultimativer Minibelader 54 | rapid-mk1-miniloader=Schneller Minibelader Mk1 55 | rapid-mk2-miniloader=Schneller Minibelader Mk2 56 | ub-ultra-fast-miniloader=Ultraschneller Minibelader 57 | ub-extreme-fast-miniloader=Extrem schneller Minibelader 58 | ub-ultra-express-miniloader=Ultra Express Minibelader 59 | ub-extreme-express-miniloader=Extrem Express Minibelader 60 | ub-ultimate-miniloader=Ultimativer Minibelader 61 | expedited-miniloader=Beschleunigter Minibelader 62 | space-miniloader=Weltraum-Minibelader 63 | deep-space-miniloader=Tiefraum Minibelader 64 | k-miniloader=Überlegener Minibelader 65 | kr-advanced-miniloader=Fortgeschrittener Minibelader 66 | kr-superior-miniloader=Überlegener Minibelader 67 | nuclear-miniloader=Nuklear Minibelader 68 | plutonium-miniloader=Plutonium Minibelader 69 | 70 | [technology-description] 71 | basic-miniloader=Einfacher Minibelader 72 | miniloader=Minibelader 73 | fast-miniloader=Schneller Minibelader 74 | express-miniloader=Express-Minibelader 75 | turbo-miniloader=Turbo-Minibelader 76 | ultimate-miniloader=Ultimativer Minibelader 77 | rapid-mk1-miniloader=Schneller Minibelader Mk1 78 | rapid-mk2-miniloader=Schneller Minibelader Mk2 79 | ub-ultra-fast-miniloader=Ultraschneller Minibelader 80 | ub-extreme-fast-miniloader=Extrem schneller Minibelader 81 | ub-ultra-express-miniloader=Ultra Express Minibelader 82 | ub-extreme-express-miniloader=Extrem Express Minibelader 83 | ub-ultimate-miniloader=Ultimativer Minibelader 84 | expedited-miniloader=Beschleunigter Minibelader 85 | space-miniloader=Weltraum-Minibelader 86 | deep-space-miniloader=Tiefraum Minibelader 87 | k-miniloader=Überlegener Minibelader 88 | kr-advanced-miniloader=Fortgeschrittener Minibelader 89 | kr-superior-miniloader=Überlegener Minibelader 90 | nuclear-miniloader=Erweiterter Miniloader, mit Uran bestückt 91 | plutonium-miniloader=Noch fortgeschrittenerer Miniloader, bestückt mit Plutonium 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Normale Mini-Belader aktivieren 95 | miniloader-enable-filter=Filternde Mini-Belader aktivieren 96 | miniloader-enable-chute=Beladerampe aktivieren 97 | miniloader-energy-usage=Mini-Belader verbrauchen Strom 98 | miniloader-snapping=Mini-Belader einrasten 99 | miniloader-double-recipes=Baupläne verdoppeln 100 | miniloader-lock-stack-sizes=Stapelgrößen festsetzen 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Wenn aktiviert, müssen Mini-Belader an das Stromnetz angeschlossen werden. 104 | miniloader-snapping=Orientierung von Mini-Beladern an angrenzenden Fließbändern ausrichten. 105 | miniloader-double-recipes=Verdoppelt Komponenten und Produkte von Bauplänen, damit Unterirdische Fließbänder in Paaren verarbeitet werden. 106 | miniloader-lock-stack-sizes=Wenn aktiviert, werden Mini-Belader Gegenstände immer einzeln bewegen. Deaktivieren erlaubt die verwendung unbegrenzter Stapelgrößen. Letzteres reduziert die Rechenlast, aber erzeugt unregelmäßigeres Transportverhalten. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Spurspaltungs-Konfiguration 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/en/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Chute 3 | basic-miniloader=Basic miniloader 4 | miniloader=Miniloader 5 | fast-miniloader=Fast miniloader 6 | express-miniloader=Express miniloader 7 | turbo-miniloader=Turbo miniloader 8 | ultimate-miniloader=Ultimate miniloader 9 | rapid-mk1-miniloader=Rapid miniloader Mk1 10 | rapid-mk2-miniloader=Rapid miniloader Mk2 11 | ub-ultra-fast-miniloader=Ultra fast miniloader 12 | ub-extreme-fast-miniloader=Extreme fast miniloader 13 | ub-ultra-express-miniloader=Ultra express miniloader 14 | ub-extreme-express-miniloader=Extreme express miniloader 15 | ub-ultimate-miniloader=Ultimate miniloader 16 | expedited-miniloader=Expedited miniloader 17 | space-miniloader=Space miniloader 18 | deep-space-miniloader=Deep space miniloader 19 | k-miniloader=Superior miniloader 20 | kr-advanced-miniloader=Advanced miniloader 21 | kr-superior-miniloader=Superior miniloader 22 | nuclear-miniloader=Nuclear miniloader 23 | plutonium-miniloader=Plutonium miniloader 24 | 25 | basic-filter-miniloader=Basic filter miniloader 26 | filter-miniloader=Filter miniloader 27 | fast-filter-miniloader=Fast filter miniloader 28 | express-filter-miniloader=Express filter miniloader 29 | turbo-filter-miniloader=Turbo filter miniloader 30 | ultimate-filter-miniloader=Ultimate filter miniloader 31 | rapid-mk1-filter-miniloader=Rapid filter miniloader Mk1 32 | rapid-mk2-filter-miniloader=Rapid filter miniloader Mk2 33 | ub-ultra-fast-filter-miniloader=Ultra fast filter miniloader 34 | ub-extreme-fast-filter-miniloader=Extreme fast filter miniloader 35 | ub-ultra-express-filter-miniloader=Ultra express filter miniloader 36 | ub-extreme-express-filter-miniloader=Extreme express filter miniloader 37 | ub-ultimate-filter-miniloader=Ultimate filter miniloader 38 | expedited-filter-miniloader=Expedited filter miniloader 39 | space-filter-miniloader=Space filter miniloader 40 | deep-space-filter-miniloader=Deep space filter miniloader 41 | k-filter-miniloader=Superior filter miniloader 42 | kr-advanced-filter-miniloader=Advanced filter miniloader 43 | kr-superior-filter-miniloader=Superior filter miniloader 44 | nuclear-filter-miniloader=Nuclear filter miniloader 45 | plutonium-filter-miniloader=Plutonium filter miniloader 46 | 47 | [technology-name] 48 | basic-miniloader=Basic miniloader 49 | miniloader=Miniloader 50 | fast-miniloader=Fast miniloader 51 | express-miniloader=Express miniloader 52 | turbo-miniloader=Turbo miniloader 53 | ultimate-miniloader=Ultimate miniloader 54 | rapid-mk1-miniloader=Rapid miniloader Mk1 55 | rapid-mk2-miniloader=Rapid miniloader Mk2 56 | ub-ultra-fast-miniloader=Ultra fast miniloader 57 | ub-extreme-fast-miniloader=Extreme fast miniloader 58 | ub-ultra-express-miniloader=Ultra express miniloader 59 | ub-extreme-express-miniloader=Extreme express miniloader 60 | ub-ultimate-miniloader=Ultimate miniloader 61 | expedited-miniloader=Expedited miniloader 62 | space-miniloader=Space miniloader 63 | deep-space-miniloader=Deep space miniloader 64 | k-miniloader=Superior miniloader 65 | kr-advanced-miniloader=Advanced miniloader 66 | kr-superior-miniloader=Superior miniloader 67 | nuclear-miniloader=Nuclear miniloader 68 | plutonium-miniloader=Plutonium miniloader 69 | 70 | [technology-description] 71 | basic-miniloader=Basic miniloader 72 | miniloader=Miniloader 73 | fast-miniloader=Fast miniloader 74 | express-miniloader=Express miniloader 75 | turbo-miniloader=Turbo miniloader 76 | ultimate-miniloader=Ultimate miniloader 77 | rapid-mk1-miniloader=Rapid miniloader Mk1 78 | rapid-mk2-miniloader=Rapid miniloader Mk2 79 | ub-ultra-fast-miniloader=Ultra fast miniloader 80 | ub-extreme-fast-miniloader=Extreme fast miniloader 81 | ub-ultra-express-miniloader=Ultra express miniloader 82 | ub-extreme-express-miniloader=Extreme express miniloader 83 | ub-ultimate-miniloader=Ultimate miniloader 84 | expedited-miniloader=Expedited miniloader 85 | space-miniloader=Space miniloader 86 | deep-space-miniloader=Deep space miniloader 87 | k-miniloader=Superior miniloader 88 | kr-advanced-miniloader=Advanced miniloader 89 | kr-superior-miniloader=Superior miniloader 90 | nuclear-miniloader=Advanced miniloader, empowered with Uranium 91 | plutonium-miniloader=Even more advanced miniloader, empowered with Plutonium 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Enable standard miniloaders 95 | miniloader-enable-filter=Enable filter miniloaders 96 | miniloader-enable-chute=Enable chute 97 | miniloader-energy-usage=Miniloaders use energy 98 | miniloader-snapping=Snap miniloaders 99 | miniloader-double-recipes=Double recipes 100 | miniloader-lock-stack-sizes=Lock stack sizes 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=When set, miniloaders must be connected to an electric network. 104 | miniloader-snapping=Snap miniloaders to the belts when built or adjacent belts are rotated. 105 | miniloader-double-recipes=Doubles cost and results of recipes, to consume underground belts in pairs. 106 | miniloader-lock-stack-sizes=When true, miniloaders will always move items one at a time. Setting this to false allows unlimited stack sizes to be used. This will reduce UPS consumption, but reduces how consistently items are moved around. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Split lane configuration 110 | -------------------------------------------------------------------------------- /locale/fr/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Goulotte 3 | basic-miniloader=Mini-chargeur basique 4 | miniloader=Mini-chargeur 5 | fast-miniloader=Mini-chargeur rapide 6 | express-miniloader=Mini-chargeur express 7 | turbo-miniloader=Mini-chargeur turbo 8 | ultimate-miniloader=Mini-chargeur ultime 9 | rapid-mk1-miniloader=Mini-chargeur rapide Mk1 10 | rapid-mk2-miniloader=Mini-chargeur rapide Mk2 11 | ub-ultra-fast-miniloader=Mini-chargeur ultra rapide 12 | ub-extreme-fast-miniloader=Mini-chargeur extrêmement rapide 13 | ub-ultra-express-miniloader=Mini-chargeur ultra express 14 | ub-extreme-express-miniloader=Mini-chargeur extrêmement express 15 | ub-ultimate-miniloader=Mini-chargeur ultime 16 | expedited-miniloader=Mini-chargeur accéléré 17 | space-miniloader=Mini-chargeur spatial 18 | deep-space-miniloader=Mini-chargeur spatial 19 | k-miniloader=Mini-chargeur supérieur 20 | kr-advanced-miniloader=Mini-chargeur avancé 21 | kr-superior-miniloader=Mini-chargeur supérieur 22 | nuclear-miniloader=Mini-chargeur nucléaire 23 | plutonium-miniloader=Mini-chargeur au plutonium 24 | 25 | basic-filter-miniloader=Mini-chargeur filtrable basique 26 | filter-miniloader=Mini-chargeur filtrable 27 | fast-filter-miniloader=Mini-chargeur rapide filtrable 28 | express-filter-miniloader=Mini-chargeur express filtrable 29 | turbo-filter-miniloader=Mini-chargeur trubo filtrable 30 | ultimate-filter-miniloader=Mini-chargeur ultime filtrable 31 | rapid-mk1-filter-miniloader=Mini-chargeur rapide Mk1 filtrable 32 | rapid-mk2-filter-miniloader=Mini-chargeur rapide Mk2 filtrable 33 | ub-ultra-fast-filter-miniloader=Mini-chargeur ultra rapide filtrable 34 | ub-extreme-fast-filter-miniloader=Mini-chargeur extrêmement rapide filtrable 35 | ub-ultra-express-filter-miniloader=Mini-chargeur ultra express filtrable 36 | ub-extreme-express-filter-miniloader=Mini-chargeur extrêmement express filtrable 37 | ub-ultimate-filter-miniloader=Mini-chargeur ultime filtrable 38 | expedited-filter-miniloader=Mini-chargeur accéléré filtrable 39 | space-filter-miniloader=Mini-chargeur filtrable spatial 40 | deep-space-filter-miniloader=Mini-chargeur filtrable spatial 41 | k-filter-miniloader=Mini-chargeur filtrable supérieur 42 | kr-advanced-filter-miniloader=Mini-chargeur filtrable avancé 43 | kr-superior-filter-miniloader=Mini-chargeur filtrable supérieur 44 | nuclear-filter-miniloader=Mini-chargeur filtrable nucléaire 45 | plutonium-filter-miniloader=Mini-chargeur filtrable au plutonium 46 | 47 | [technology-name] 48 | basic-miniloader=Mini-chargeur basique 49 | miniloader=Mini-chargeur 50 | fast-miniloader=Mini-chargeur rapide 51 | express-miniloader=Mini-chargeur express 52 | turbo-miniloader=Mini-chargeur turbo 53 | ultimate-miniloader=Mini-chargeur ultime 54 | rapid-mk1-miniloader=Mini-chargeur rapide Mk1 55 | rapid-mk2-miniloader=Mini-chargeur rapide Mk2 56 | ub-ultra-fast-miniloader=Mini-chargeur ultra rapide 57 | ub-extreme-fast-miniloader=Mini-chargeur extrêmement rapide 58 | ub-ultra-express-miniloader=Mini-chargeur ultra express 59 | ub-extreme-express-miniloader=Mini-chargeur extrêmement express 60 | ub-ultimate-miniloader=Mini-chargeur ultime 61 | expedited-miniloader=Mini-chargeur accéléré 62 | space-miniloader=Mini-chargeur spatial 63 | deep-space-miniloader=Mini-chargeur spatial 64 | k-miniloader=Mini-chargeur supérieur 65 | kr-advanced-miniloader=Mini-chargeur avancé 66 | kr-superior-miniloader=Mini-chargeur supérieur 67 | nuclear-miniloader=Mini-chargeur nucléaire 68 | plutonium-miniloader=Mini-chargeur au plutonium 69 | 70 | [technology-description] 71 | basic-miniloader=Mini-chargeur basique 72 | miniloader=Petit chargeur permettant de faire la liaison entre un convoyeur et une entité, par exemple une machine. 73 | fast-miniloader=Version améliorée du mini-chargeur. 74 | express-miniloader=Version améliorée du mini-chargeur rapide. 75 | turbo-miniloader=Version améliorée du mini-chargeur express. 76 | ultimate-miniloader=Version améliorée du mini-chargeur ultime 77 | rapid-mk1-miniloader=Mini-chargeur rapide Mk1 78 | rapid-mk2-miniloader=Mini-chargeur rapide Mk2 79 | ub-ultra-fast-miniloader=Mini-chargeur ultra rapide 80 | ub-extreme-fast-miniloader=Mini-chargeur extrêmement rapide 81 | ub-ultra-express-miniloader=Mini-chargeur ultra express 82 | ub-extreme-express-miniloader=Mini-chargeur extrêmement express 83 | ub-ultimate-miniloader=Mini-chargeur ultime 84 | expedited-miniloader=Mini-chargeur accéléré 85 | space-miniloader=Mini-chargeur spatial 86 | deep-space-miniloader=Mini-chargeur spatial 87 | k-miniloader=Mini-chargeur supérieur 88 | kr-advanced-miniloader=Mini-chargeur avancé 89 | kr-superior-miniloader=Mini-chargeur supérieur 90 | nuclear-miniloader=Mini-chargeur avancé, imprégné d'uranium 91 | plutonium-miniloader=Mini-chargeur encore plus avancé, imprégné de Plutonium 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Activer les mini-chargeurs standards 95 | miniloader-enable-filter=Activer les mini-chargeurs filtrables 96 | miniloader-enable-chute=Activer les chutes 97 | miniloader-energy-usage=Les mini-chargeurs consomment de l'énergie 98 | miniloader-snapping=Clipser les mini-chargeurs 99 | miniloader-double-recipes=Double recettes 100 | miniloader-lock-stack-sizes=Verrouiller la taille de la pile 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Lorsque activé, les mini-chargeurs doivent être connectés à un réseau électrique. 104 | miniloader-snapping=Fixe les mini-chargeurs aux convoyeurs lorsque vous construisez les convoyeurs ou lorsque vous faites pivoter les convoyeurs adjacents. 105 | miniloader-double-recipes=Double le coût et le rendement des recettes pour consommer les convoyeurs souterrains par paire. 106 | miniloader-lock-stack-sizes=Quand activé, les mini-chargeurs déplaceront toujours un objet à la fois. Désactiver cette option permet d'utiliser des tailles de pile illimitées. Cela réduira l'impact sur l'UPS, mais réduira la façon dont les objets sont continuellement déplacés. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Configuration de la répartition des voies 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/it/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Scivolo 3 | basic-miniloader=Minicaricatore di base 4 | miniloader=Mini-caricatore 5 | fast-miniloader=Mini-caricatore veloce 6 | express-miniloader=Mini-caricatore express 7 | turbo-miniloader=Mini-caricatore turbo 8 | ultimate-miniloader=Mini-caricatore definitivo 9 | rapid-mk1-miniloader=Mini-caricatore rapido Mk1 10 | rapid-mk2-miniloader=Mini-caricatore rapido Mk2 11 | ub-ultra-fast-miniloader=Mini-caricatore ultra veloce 12 | ub-extreme-fast-miniloader=Mini-caricatore estremamente veloce 13 | ub-ultra-express-miniloader=Mini-caricatore express ultra 14 | ub-extreme-express-miniloader=Mini-caricatore express estremo 15 | ub-ultimate-miniloader=Mini-caricatore definitivo 16 | expedited-miniloader=Mini-caricatore spedito 17 | space-miniloader=Mini-caricatore spaziale 18 | k-miniloader=Mini-caricatore superiore 19 | kr-advanced-miniloader=Mini-caricatore avanzato 20 | kr-superior-miniloader=Mini-caricatore superiore 21 | nuclear-miniloader=Mini-caricatore nucleare 22 | plutonium-miniloader=Mini-caricatore al plutonio 23 | 24 | basic-filter-miniloader=Mini-caricatore filtro di base 25 | filter-miniloader=Mini-caricatore del filtro 26 | fast-filter-miniloader=Mini-caricatore veloce del filtro 27 | express-filter-miniloader=Mini-caricatore del filtro express 28 | turbo-filter-miniloader=Mini-caricatore del filtro turbo 29 | ultimate-filter-miniloader=Mini-caricatore del filtro definitivo 30 | rapid-mk1-filter-miniloader=Mini-caricatore del filtro rapido Mk1 31 | rapid-mk2-filter-miniloader=Mini-caricatore del filtro rapido Mk2 32 | ub-ultra-fast-filter-miniloader=Mini-caricatore del filtro ultraveloce 33 | ub-extreme-fast-filter-miniloader=Mini-caricatore del filtro estremamente veloce 34 | ub-ultra-express-filter-miniloader=Mini-caricatore del filtro express ultra 35 | ub-extreme-express-filter-miniloader=Mini-caricatore del filtro express estremo 36 | ub-ultimate-filter-miniloader=Mini-caricatore del filtro definitivo 37 | expedited-filter-miniloader=Mini-caricatore del filtro spedito 38 | space-filter-miniloader=Mini-caricatore del filtro spaziale 39 | k-filter-miniloader=Mini-caricatore del filtro superiore 40 | kr-advanced-filter-miniloader=Mini-caricatore del filtro avanzato 41 | kr-superior-filter-miniloader=Mini-caricatore del filtro superiore 42 | nuclear-filter-miniloader=Mini-caricatore del filtro nucleare 43 | plutonium-filter-miniloader=Mini-caricatore del filtro al plutonio 44 | 45 | [technology-name] 46 | basic-miniloader=Minicaricatore di base 47 | miniloader=Mini-caricatore 48 | fast-miniloader=Mini-caricatore veloce 49 | express-miniloader=Mini-caricatore express 50 | turbo-miniloader=Mini-caricatore turbo 51 | ultimate-miniloader=Mini-caricatore definitivo 52 | rapid-mk1-miniloader=Mini-caricatore rapido Mk1 53 | rapid-mk2-miniloader=Mini-caricatore rapido Mk2 54 | ub-ultra-fast-miniloader=Mini-caricatore ultra veloce 55 | ub-extreme-fast-miniloader=Mini-caricatore estremamente veloce 56 | ub-ultra-express-miniloader=Mini-caricatore express ultra 57 | ub-extreme-express-miniloader=Mini-caricatore express estremo 58 | ub-ultimate-miniloader=Mini-caricatore definitivo 59 | expedited-miniloader=Mini-caricatore spedito 60 | space-miniloader=Mini-caricatore spaziale 61 | k-miniloader=Mini-caricatore superiore 62 | kr-advanced-miniloader=Mini-caricatore avanzato 63 | kr-superior-miniloader=Mini-caricatore superiore 64 | nuclear-miniloader=Mini-caricatore nucleare 65 | plutonium-miniloader=Mini-caricatore al plutonio 66 | 67 | [technology-description] 68 | basic-miniloader=Minicaricatore di base 69 | miniloader=Mini-caricatore 70 | fast-miniloader=Mini-caricatore veloce 71 | express-miniloader=Mini-caricatore express 72 | turbo-miniloader=Mini-caricatore turbo 73 | ultimate-miniloader=Mini-caricatore definitivo 74 | rapid-mk1-miniloader=Mini-caricatore rapido Mk1 75 | rapid-mk2-miniloader=Mini-caricatore rapido Mk2 76 | ub-ultra-fast-miniloader=Mini-caricatore ultra veloce 77 | ub-extreme-fast-miniloader=Mini-caricatore estremamente veloce 78 | ub-ultra-express-miniloader=Mini-caricatore express ultra 79 | ub-extreme-express-miniloader=Mini-caricatore express estremo 80 | ub-ultimate-miniloader=Mini-caricatore definitivo 81 | expedited-miniloader=Mini-caricatore spedito 82 | space-miniloader=Mini-caricatore spaziale 83 | k-miniloader=Mini-caricatore superiore 84 | kr-advanced-miniloader=Mini-caricatore avanzato 85 | kr-superior-miniloader=Mini-caricatore superiore 86 | nuclear-miniloader=Mini-caricatore avanzato, alimentato con l'Uranio 87 | plutonium-miniloader=Mini-caricatore ancor più avanzato, alimentato con il Plutonio 88 | 89 | [mod-setting-name] 90 | miniloader-enable-standard=Abilita i mini-caricatori standard 91 | miniloader-enable-filter=Abilita i mini-caricatori del filtro 92 | miniloader-enable-chute=Abilita scivolo 93 | miniloader-energy-usage=I mini-caricatori usano energia 94 | miniloader-snapping=Aggancia mini-caricatori 95 | miniloader-double-recipes=Ricette doppie 96 | miniloader-lock-stack-sizes=Blocca dimensioni pila 97 | 98 | [mod-setting-description] 99 | miniloader-energy-usage=Quando impostato, i mini-caricatori devono essere connessi ad una rete elettrica. 100 | miniloader-snapping=Aggancia i mini-caricatori ai nastri trasportatori quando costruiti o quelli adiacenti sono ruotati. 101 | miniloader-double-recipes=Raddoppia il costo ed i risultati delle ricette, per consumare i nastri sotterranei a coppie. 102 | miniloader-lock-stack-sizes=Quando true, i mini-caricatori sposteranno sempre gli elementi uno per volta. Impostarlo a false consente dimensioni illimitate di pile da utilizzare. Questo ridurrà il consumo di UPS, ma riduce quanto costantemente gli elementi sono spostati in giro. 103 | 104 | [miniloader-gui] 105 | 106 | 107 | -------------------------------------------------------------------------------- /locale/ja/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=シュート 3 | basic-miniloader=基本ミニローダー 4 | miniloader=ミニローダー 5 | fast-miniloader=高速ミニローダー 6 | express-miniloader=超高速ミニローダー 7 | turbo-miniloader=ターボミニローダー 8 | ultimate-miniloader=アルティメットミニローダー 9 | ub-ultimate-miniloader=アルティメットミニローダー 10 | space-miniloader=宇宙用ミニローダー 11 | deep-space-miniloader=深宇宙ミニローダー 12 | k-miniloader=神速ミニローダー 13 | kr-advanced-miniloader=強化ミニローダー 14 | kr-superior-miniloader=神速ミニローダー 15 | nuclear-miniloader=核ミニローダー 16 | plutonium-miniloader=プルトニウムミニローダー 17 | 18 | basic-filter-miniloader=基本フィルターミニローダー 19 | filter-miniloader=フィルターミニローダー 20 | fast-filter-miniloader=高速フィルターミニローダー 21 | express-filter-miniloader=超高速フィルターミニローダー 22 | turbo-filter-miniloader=ターボフィルターミニローダー 23 | ultimate-filter-miniloader=アルティメットフィルターミニローダー 24 | ub-ultimate-filter-miniloader=アルティメットフィルターミニローダー 25 | space-filter-miniloader=宇宙用フィルターミニローダー 26 | deep-space-filter-miniloader=深宇宙フィルターミニローダー 27 | k-filter-miniloader=神速フィルターミニローダー 28 | kr-advanced-filter-miniloader=強化フィルターミニローダー 29 | kr-superior-filter-miniloader=神速フィルターミニローダー 30 | nuclear-filter-miniloader=核フィルターミニローダー 31 | plutonium-filter-miniloader=プルトニウムフィルターミニローダー 32 | 33 | [technology-name] 34 | basic-miniloader=基本ミニローダー 35 | miniloader=ミニローダー 36 | fast-miniloader=高速ミニローダー 37 | express-miniloader=超高速ミニローダー 38 | turbo-miniloader=ターボミニローダー 39 | ultimate-miniloader=アルティメットミニローダー 40 | ub-ultimate-miniloader=アルティメットミニローダー 41 | space-miniloader=宇宙用ミニローダー 42 | deep-space-miniloader=深宇宙ミニローダー 43 | k-miniloader=神速ミニローダー 44 | kr-advanced-miniloader=強化ミニローダー 45 | kr-superior-miniloader=神速ミニローダー 46 | nuclear-miniloader=核ミニローダー 47 | plutonium-miniloader=プルトニウムミニローダー 48 | 49 | [technology-description] 50 | basic-miniloader=基本ミニローダー 51 | miniloader=ミニローダー 52 | fast-miniloader=高速ミニローダー 53 | express-miniloader=超高速ミニローダー 54 | turbo-miniloader=ターボミニローダー 55 | ultimate-miniloader=アルティメットミニローダー 56 | ub-ultimate-miniloader=アルティメットミニローダー 57 | space-miniloader=宇宙用ミニローダー 58 | deep-space-miniloader=深宇宙ミニローダー 59 | k-miniloader=神速ミニローダー 60 | kr-advanced-miniloader=強化ミニローダー 61 | kr-superior-miniloader=神速ミニローダー 62 | 63 | [mod-setting-name] 64 | miniloader-enable-standard=標準的なミニローダーを有効にする 65 | miniloader-enable-filter=フィルターミニローダーを有効にする 66 | miniloader-enable-chute=シュートを有効にする 67 | miniloader-snapping=ミニローダーのスナップ 68 | 69 | [mod-setting-description] 70 | miniloader-snapping=設置時や隣接するベルトが回転したとき、ミニローダーをベルトに自動的にスナップします。 71 | 72 | [miniloader-gui] 73 | 74 | 75 | -------------------------------------------------------------------------------- /locale/ko/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=활송 장치 3 | basic-miniloader=기초 소형 적재기 4 | miniloader=소형 적재기 5 | fast-miniloader=빠른 소형 적재기 6 | express-miniloader=고속 소형 적재기 7 | ub-extreme-express-miniloader=극고속 소형 적재기 8 | space-miniloader=우주 소형 적재기 9 | nuclear-miniloader=핵 소형 적재기 10 | plutonium-miniloader=플루토늄 소형 적재기 11 | 12 | basic-filter-miniloader=기초 선별 소형 적재기 13 | filter-miniloader=선별 소형 적재기 14 | fast-filter-miniloader=빠른 선별 소형 적재기 15 | express-filter-miniloader=고속 선별 소형 적재기 16 | 17 | [technology-name] 18 | basic-miniloader=기초 소형 적재기 19 | miniloader=소형 적재기 20 | fast-miniloader=빠른 소형 적재기 21 | express-miniloader=고속 소형 적재기 22 | ub-extreme-express-miniloader=극고속 소형 적재기 23 | space-miniloader=우주 소형 적재기 24 | nuclear-miniloader=핵 소형 적재기 25 | plutonium-miniloader=플루토늄 소형 적재기 26 | 27 | [technology-description] 28 | basic-miniloader=기초 소형 적재기 29 | miniloader=소형 적재기 30 | fast-miniloader=빠른 소형 적재기 31 | express-miniloader=고속 소형 적재기 32 | ub-extreme-express-miniloader=극고속 소형 적재기 33 | space-miniloader=우주 소형 적재기 34 | 35 | [mod-setting-name] 36 | miniloader-enable-standard=기초 소형 적재기 활성화 37 | miniloader-enable-filter=선별 소형 적재기 활성화 38 | miniloader-enable-chute=활송 장치 활성화 39 | miniloader-energy-usage=소형 적재기가 전력을 사용 40 | miniloader-snapping=소형 적재기 자동 삽입 41 | miniloader-double-recipes=조합법 짝 맞추기 42 | miniloader-lock-stack-sizes=아이템 스택 크기 고정 43 | 44 | [mod-setting-description] 45 | miniloader-energy-usage=설정되었을 경우, 소형 적재기를 사용하려면 전력망에 연결되어 있어야 합니다. 46 | miniloader-snapping=소형 적재기를 설치 할 때 자동적으로 방향을 맞춰줍니다. 47 | miniloader-double-recipes=지하 벨트를 2개씩 소모하도록, 제작법의 제작 수량과 비용을 2배로 설정합니다. 48 | miniloader-lock-stack-sizes=활성화된 경우, 미니로더는 항상 항목을 한 번에 하나씩 이동합니다. 바활성화된 경우 한 번에 무제한의 아이템을 이동할 수 있습니다. 이렇게 하면 UPS 소비는 줄어들지만, 항목의 일관성 있는 이동은 줄어듭니다. 49 | 50 | [miniloader-gui] 51 | 52 | 53 | -------------------------------------------------------------------------------- /locale/pt-BR/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Funil 3 | basic-miniloader=Minicarregador básico 4 | miniloader=Minicarregador 5 | fast-miniloader=Minicarregador rápido 6 | express-miniloader=Minicarregador expresso 7 | turbo-miniloader=Minicarregador turbo 8 | ultimate-miniloader=Minicarregador definitivo 9 | rapid-mk1-miniloader=Minicarregador rápido Mk1 10 | rapid-mk2-miniloader=Minicarregador rápido Mk2 11 | ub-ultra-fast-miniloader=Minicarregador ultra rápido 12 | ub-extreme-fast-miniloader=Minicarregador extremamente rápido 13 | ub-ultra-express-miniloader=Minicarregador ultra expresso 14 | ub-extreme-express-miniloader=Minicarregador extremamente expresso 15 | ub-ultimate-miniloader=Minicarregador definitivo 16 | expedited-miniloader=Minicarregador expedido 17 | space-miniloader=Minicarregador espacial 18 | deep-space-miniloader=Minicarregador do espaõ profundo 19 | k-miniloader=Minicarregador superior 20 | kr-advanced-miniloader=Minicarregador avançado 21 | kr-superior-miniloader=Minicarregador superior 22 | nuclear-miniloader=Minicarregador nuclear 23 | plutonium-miniloader=Minicarregador de plutônio 24 | 25 | basic-filter-miniloader=Minicarregador com filtro básico 26 | filter-miniloader=Minicarregador com filtro 27 | fast-filter-miniloader=Minicarregador com filtro rápido 28 | express-filter-miniloader=Minicarregador com filtro expresso 29 | turbo-filter-miniloader=Minicarregador com filtro turbo 30 | ultimate-filter-miniloader=Minicarregador com filtro definitivo 31 | rapid-mk1-filter-miniloader=Minicarregador com filtro rápido Mk1 32 | rapid-mk2-filter-miniloader=Minicarregador com filtro rápido Mk2 33 | ub-ultra-fast-filter-miniloader=Minicarregador com filtro ultra rápido 34 | ub-extreme-fast-filter-miniloader=Minicarregador com filtro extremamente rápido 35 | ub-ultra-express-filter-miniloader=Minicarregador com filtro ultra expresso 36 | ub-extreme-express-filter-miniloader=Minicarregador com filtro extrememante expresso 37 | ub-ultimate-filter-miniloader=Minicarregador com filtro definitivo 38 | expedited-filter-miniloader=Minicarregador com filtro expedido 39 | space-filter-miniloader=Minicarregador com filtro espacial 40 | deep-space-filter-miniloader=Minicarregador com filtro do espaço profundo 41 | k-filter-miniloader=Minicarregador com filtro superior 42 | kr-advanced-filter-miniloader=Minicarregador com filtro avançado 43 | kr-superior-filter-miniloader=Minicarregador com filtro superior 44 | nuclear-filter-miniloader=Minicarregador com filtro nuclear 45 | plutonium-filter-miniloader=Minicarregador com filtro de plutônio 46 | 47 | [technology-name] 48 | basic-miniloader=Minicarregador básico 49 | miniloader=Minicarregador 50 | fast-miniloader=Minicarregador rápido 51 | express-miniloader=Minicarregador expresso 52 | turbo-miniloader=Minicarregador turbo 53 | ultimate-miniloader=Minicarregador definitivo 54 | rapid-mk1-miniloader=Minicarregador rápido Mk1 55 | rapid-mk2-miniloader=Minicarregador rápido Mk2 56 | ub-ultra-fast-miniloader=Minicarregador ultra rápido 57 | ub-extreme-fast-miniloader=Minicarregador extremamente rápido 58 | ub-ultra-express-miniloader=Minicarregador ultra expresso 59 | ub-extreme-express-miniloader=Minicarregador extremamente expresso 60 | ub-ultimate-miniloader=Minicarregador definitivo 61 | expedited-miniloader=Minicarregador expedido 62 | space-miniloader=Minicarregador espacial 63 | deep-space-miniloader=Minicarregador do espaõ profundo 64 | k-miniloader=Minicarregador superior 65 | kr-advanced-miniloader=Minicarregador avançado 66 | kr-superior-miniloader=Minicarregador superior 67 | nuclear-miniloader=Minicarregador nuclear 68 | plutonium-miniloader=Minicarregador de plutônio 69 | 70 | [technology-description] 71 | basic-miniloader=Minicarregador básico 72 | miniloader=Minicarregador 73 | fast-miniloader=Minicarregador rápido 74 | express-miniloader=Minicarregador expresso 75 | turbo-miniloader=Minicarregador turbo 76 | ultimate-miniloader=Minicarregador definitivo 77 | rapid-mk1-miniloader=Minicarregador rápido Mk1 78 | rapid-mk2-miniloader=Minicarregador rápido Mk2 79 | ub-ultra-fast-miniloader=Minicarregador ultra rápido 80 | ub-extreme-fast-miniloader=Minicarregador extremamente rápido 81 | ub-ultra-express-miniloader=Minicarregador ultra expresso 82 | ub-extreme-express-miniloader=Minicarregador extremamente expresso 83 | ub-ultimate-miniloader=Minicarregador definitivo 84 | expedited-miniloader=Minicarregador expedido 85 | space-miniloader=Minicarregador espacial 86 | deep-space-miniloader=Minicarregador do espaõ profundo 87 | k-miniloader=Minicarregador superior 88 | kr-advanced-miniloader=Minicarregador avançado 89 | kr-superior-miniloader=Minicarregador superior 90 | nuclear-miniloader=Minicarregador avançado, fortalecido com urânio 91 | plutonium-miniloader=Minicarregador ainda mais avançado, fortalecido com plutônio 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Habilitar minicarregadores padrões 95 | miniloader-enable-filter=Habilitar minicarregadores com filtro 96 | miniloader-enable-chute=Habilitar rampa 97 | miniloader-energy-usage=Minicarregadores usam energia 98 | miniloader-snapping=Ajustar minicarregadores 99 | miniloader-double-recipes=Duplicar receitas 100 | miniloader-lock-stack-sizes=Bloquear tamanho das pilhas 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Quando marcado, minicarregadores devem estar conectados a uma rede elétrica. 104 | miniloader-snapping=Ajusta minicarregadores nas esteiras quando for construídas ou esteiras adjacentes são rotacionadas. 105 | miniloader-double-recipes=Duplica custos e resultados de receitas, para consumir esteiras subterrâneas em pares. 106 | miniloader-lock-stack-sizes=Se marcado, os minicarregadores sempre moverão os itens um de cada vez. Desmarcar permite que sejam usados os tamanhos de pilhas ilimitados. Isso reduzirá o consumo do UPS, mas reduz o quão consistentemente os itens são movidos. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Configuração de divisão de linha 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/ru/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Скат 3 | basic-miniloader=Простой мини-погрузчик 4 | miniloader=Мини-погрузчик 5 | fast-miniloader=Быстрый мини-погрузчик 6 | express-miniloader=Экспресс мини-погрузчик 7 | turbo-miniloader=Турбо мини-погрузчик 8 | ultimate-miniloader=Наилучший мини-погрузчик 9 | rapid-mk1-miniloader=Быстрый мини-погрузчик МК1 10 | rapid-mk2-miniloader=Быстрый мини-погрузчик МК2 11 | ub-ultra-fast-miniloader=Ультра-быстрый мини-погрузчик 12 | ub-extreme-fast-miniloader=Экстремально быстрый мини-погрузчик 13 | ub-ultra-express-miniloader=Ультра-экспресс мини-погрузчик 14 | ub-extreme-express-miniloader=Экстремально-экспресс мини-погрузчик 15 | ub-ultimate-miniloader=Наилучший мини-погрузчик 16 | expedited-miniloader=Ускоренный мини-погрузчик 17 | space-miniloader=Космический мини-погрузчик 18 | deep-space-miniloader=Мини-погрузчик глубокого космоса 19 | k-miniloader=Превосходный мини-погрузчик 20 | kr-advanced-miniloader=Продвинутый мини-погрузчик 21 | kr-superior-miniloader=Превосходный мини-погрузчик 22 | nuclear-miniloader=Ядерный мини-погрузчик 23 | plutonium-miniloader=Плутониевый мини-погрузчик 24 | 25 | basic-filter-miniloader=Простой фильтрующий мини-погрузчик 26 | filter-miniloader=Фильтрующий мини-погрузчик 27 | fast-filter-miniloader=Быстрый фильтрующий мини-погрузчик 28 | express-filter-miniloader=Экспресс фильтрующий мини-погрузчик 29 | turbo-filter-miniloader=Турбо фильтрующий мини-погрузчик 30 | ultimate-filter-miniloader=Наилучший фильтрующий мини-погрузчик 31 | rapid-mk1-filter-miniloader=Быстрый фильтрующий мини-погрузчик МК1 32 | rapid-mk2-filter-miniloader=Быстрый фильтрующий мини-погрузчик МК2 33 | ub-ultra-fast-filter-miniloader=Ультра-быстрый фильтрующий мини-погрузчик 34 | ub-extreme-fast-filter-miniloader=Экстремально быстрый фильтрующий мини-погрузчик 35 | ub-ultra-express-filter-miniloader=Ультра-экспресс фильтрующий мини-погрузчик 36 | ub-extreme-express-filter-miniloader=Экстремально-экспресс фильтрующий мини-погрузчик 37 | ub-ultimate-filter-miniloader=Наилучший фильтрующий мини-погрузчик 38 | expedited-filter-miniloader=Ускоренный фильтрующий мини-погрузчик 39 | space-filter-miniloader=Космический фильтрующий мини-погрузчик 40 | deep-space-filter-miniloader=Фильтрующий мини-погрузчик глубокого космоса 41 | k-filter-miniloader=Превосходный фильтрующий мини-погрузчик 42 | kr-advanced-filter-miniloader=Продвинутый фильтрующий мини-погрузчик 43 | kr-superior-filter-miniloader=Превосходный фильтрующий мини-погрузчик 44 | nuclear-filter-miniloader=Ядерный фильтрующий мини-погрузчик 45 | plutonium-filter-miniloader=Плутониевый фильтрующий мини-погрузчик 46 | 47 | [technology-name] 48 | basic-miniloader=Простой мини-погрузчик 49 | miniloader=Мини-погрузчик 50 | fast-miniloader=Быстрый мини-погрузчик 51 | express-miniloader=Экспресс мини-погрузчик 52 | turbo-miniloader=Турбо мини-погрузчик 53 | ultimate-miniloader=Наилучший мини-погрузчик 54 | rapid-mk1-miniloader=Быстрый мини-погрузчик МК1 55 | rapid-mk2-miniloader=Быстрый мини-погрузчик МК2 56 | ub-ultra-fast-miniloader=Ультра-быстрый мини-погрузчик 57 | ub-extreme-fast-miniloader=Экстремально быстрый мини-погрузчик 58 | ub-ultra-express-miniloader=Ультра-экспресс мини-погрузчик 59 | ub-extreme-express-miniloader=Экстремально-экспресс мини-погрузчик 60 | ub-ultimate-miniloader=Наилучший мини-погрузчик 61 | expedited-miniloader=Ускоренный мини-погрузчик 62 | space-miniloader=Космический мини-погрузчик 63 | deep-space-miniloader=Мини-погрузчик глубокого космоса 64 | k-miniloader=Превосходный мини-погрузчик 65 | kr-advanced-miniloader=Продвинутый мини-погрузчик 66 | kr-superior-miniloader=Превосходный мини-погрузчик 67 | nuclear-miniloader=Ядерный мини-погрузчик 68 | plutonium-miniloader=Плутониевый мини-погрузчик 69 | 70 | [technology-description] 71 | basic-miniloader=Простой мини-погрузчик 72 | miniloader=Мини-погрузчик 73 | fast-miniloader=Быстрый мини-погрузчик 74 | express-miniloader=Экспресс мини-погрузчик 75 | turbo-miniloader=Турбо мини-погрузчик 76 | ultimate-miniloader=Наилучший мини-погрузчик 77 | rapid-mk1-miniloader=Быстрый мини-погрузчик МК1 78 | rapid-mk2-miniloader=Быстрый мини-погрузчик МК2 79 | ub-ultra-fast-miniloader=Ультра-быстрый мини-погрузчик 80 | ub-extreme-fast-miniloader=Экстремально быстрый мини-погрузчик 81 | ub-ultra-express-miniloader=Ультра-экспресс мини-погрузчик 82 | ub-extreme-express-miniloader=Экстремально-экспресс мини-погрузчик 83 | ub-ultimate-miniloader=Наилучший мини-погрузчик 84 | expedited-miniloader=Ускоренный мини-погрузчик 85 | space-miniloader=Космический мини-погрузчик 86 | deep-space-miniloader=Мини-погрузчик глубокого космоса 87 | k-miniloader=Превосходный мини-погрузчик 88 | kr-advanced-miniloader=Продвинутый мини-погрузчик 89 | kr-superior-miniloader=Превосходный мини-погрузчик 90 | nuclear-miniloader=Усовершенствованный мини-погрузчик, использующий энергию урана 91 | plutonium-miniloader=Еще более усовершенствованный мини-погрузчик, использующий энергию плутония 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Включить обычные мини-погрузчики 95 | miniloader-enable-filter=Включить фильтрующие мини-погрузчики 96 | miniloader-enable-chute=Включить скат 97 | miniloader-energy-usage=Мини-погрузчики используют энергию 98 | miniloader-snapping=Переключать мини-погрузчики 99 | miniloader-double-recipes=Двойные рецепты 100 | miniloader-lock-stack-sizes=Зафиксировать размер пачки 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Если установлено, погрузчики должны быть подключены к электропитанию. 104 | miniloader-snapping=Подключать мини-погрузчики к конвейерам при постройке или когда подключенный конвейер разворачивают. 105 | miniloader-double-recipes=Удваивает стоимость и результат рецептов, чтобы потреблять подземные конвейеры парами. 106 | miniloader-lock-stack-sizes=Когда включено, мини-погрузчики всегда перемещают предметы по одному за раз. Если выключено, то можно использовать неограниченный размер пачки. Включение уменьшит потребление UPS, но также уменьшит скорость и плотность движения предметов. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Настройка разделения полос 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/uk/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=Жолоб 3 | basic-miniloader=Базовий завантажувач 4 | miniloader=Завантажувач 5 | fast-miniloader=Швидкий завантажувач 6 | express-miniloader=Експрес-завантажувач 7 | turbo-miniloader=Турбо-завантажувач 8 | ultimate-miniloader=Надшвидкий завантажувач 9 | rapid-mk1-miniloader=Швидкісний завантажувач Mk1 10 | rapid-mk2-miniloader=Швидкісний завантажувач Mk2 11 | ub-ultra-fast-miniloader=Ультра-швидкий завантажувач 12 | ub-extreme-fast-miniloader=Екстремально швидкий завантажувач 13 | ub-ultra-express-miniloader=Ультра-екстремально швидкий завантажувач 14 | ub-extreme-express-miniloader=Екстремальний експрес-завантажувач 15 | ub-ultimate-miniloader=Надшвидкий завантажувач 16 | expedited-miniloader=Прискорений завантажувач 17 | space-miniloader=Космічний завантажувач 18 | deep-space-miniloader=Завантажувач глибокого космосу 19 | k-miniloader=Найліпший завантажувач 20 | kr-advanced-miniloader=Покращений завантажувач 21 | kr-superior-miniloader=Прискорений завантажувач 22 | nuclear-miniloader=Ядерний завантажувач 23 | plutonium-miniloader=Плутонієвий завантажувач 24 | 25 | basic-filter-miniloader=Базовий фільтрувальний завантажувач 26 | filter-miniloader=Фільтрувальний завантажувач 27 | fast-filter-miniloader=Швидкий фільтрувальний завантажувач 28 | express-filter-miniloader=Фільтрувальний експрес-завантажувач 29 | turbo-filter-miniloader=Фільтрувальний турбо-завантажувач 30 | ultimate-filter-miniloader=Надшвидкий фільтрувальний завантажувач 31 | rapid-mk1-filter-miniloader=Швидкісний фільтрувальний завантажувач Mk1 32 | rapid-mk2-filter-miniloader=Швидкісний фільтрувальний завантажувач Mk2 33 | ub-ultra-fast-filter-miniloader=Ультра-швидкий фільтрувальний завантажувач 34 | ub-extreme-fast-filter-miniloader=Екстремально швидкий фільтрувальний завантажувач 35 | ub-ultra-express-filter-miniloader=Ультра-екстремально швидкий фільтрувальний завантажувач 36 | ub-extreme-express-filter-miniloader=Фільтрувальний екстремальний експрес-завантажувач 37 | ub-ultimate-filter-miniloader=Надшвидкий фільтрувальний завантажувач 38 | expedited-filter-miniloader=Прискорений фільтрувальний завантажувач 39 | space-filter-miniloader=Космічний фільтрувальний завантажувач 40 | deep-space-filter-miniloader=Фільтраційний завантажувач глибокого космосу 41 | k-filter-miniloader=Найліпший фільтрувальний завантажувач 42 | kr-advanced-filter-miniloader=Покращений фільтрувальний завантажувач 43 | kr-superior-filter-miniloader=Прискорений фільтрувальний завантажувач 44 | nuclear-filter-miniloader=Ядерний фільтрувальний завантажувач 45 | plutonium-filter-miniloader=Плутонієвий фільтрувальний завантажувач 46 | 47 | [technology-name] 48 | basic-miniloader=Базовий завантажувач 49 | miniloader=Завантажувач 50 | fast-miniloader=Швидкий завантажувач 51 | express-miniloader=Експрес-завантажувач 52 | turbo-miniloader=Турбо-завантажувач 53 | ultimate-miniloader=Надшвидкий завантажувач 54 | rapid-mk1-miniloader=Швидкісний завантажувач Mk1 55 | rapid-mk2-miniloader=Швидкісний завантажувач Mk2 56 | ub-ultra-fast-miniloader=Ультра-швидкий завантажувач 57 | ub-extreme-fast-miniloader=Екстремально швидкий завантажувач 58 | ub-ultra-express-miniloader=Ультра-екстремально швидкий завантажувач 59 | ub-extreme-express-miniloader=Екстремальний експрес-завантажувач 60 | ub-ultimate-miniloader=Надшвидкий завантажувач 61 | expedited-miniloader=Прискорений завантажувач 62 | space-miniloader=Космічний завантажувач 63 | deep-space-miniloader=Завантажувач глибокого космосу 64 | k-miniloader=Найліпший завантажувач 65 | kr-advanced-miniloader=Покращений завантажувач 66 | kr-superior-miniloader=Прискорений завантажувач 67 | nuclear-miniloader=Ядерний завантажувач 68 | plutonium-miniloader=Плутонієвий завантажувач 69 | 70 | [technology-description] 71 | basic-miniloader=Базовий завантажувач 72 | miniloader=Завантажувач 73 | fast-miniloader=Швидкий завантажувач 74 | express-miniloader=Експрес-завантажувач 75 | turbo-miniloader=Турбо-завантажувач 76 | ultimate-miniloader=Надшвидкий завантажувач 77 | rapid-mk1-miniloader=Швидкісний завантажувач Mk1 78 | rapid-mk2-miniloader=Швидкісний завантажувач Mk2 79 | ub-ultra-fast-miniloader=Ультра-швидкий завантажувач 80 | ub-extreme-fast-miniloader=Екстремально швидкий завантажувач 81 | ub-ultra-express-miniloader=Ультра-екстремально швидкий завантажувач 82 | ub-extreme-express-miniloader=Екстремальний експрес-завантажувач 83 | ub-ultimate-miniloader=Надшвидкий завантажувач 84 | expedited-miniloader=Прискорений завантажувач 85 | space-miniloader=Космічний завантажувач 86 | deep-space-miniloader=Завантажувач глибокого космосу 87 | k-miniloader=Найліпший завантажувач 88 | kr-advanced-miniloader=Покращений завантажувач 89 | kr-superior-miniloader=Прискорений завантажувач 90 | nuclear-miniloader=Покращений завантажувач, працює завдяки урану 91 | plutonium-miniloader=Ще кращий завантажувач, працює завдяки плутонію 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=Ввімкнути завантажувачі 95 | miniloader-enable-filter=Ввімкнути фільтрумальні завантажувачі 96 | miniloader-enable-chute=Ввімкнути жолоби 97 | miniloader-energy-usage=Завантажувачам потрібна енергія 98 | miniloader-snapping=Перемикати завантажувачі 99 | miniloader-double-recipes=Подвійні рецепти 100 | miniloader-lock-stack-sizes=Заблокувати розмір пачки для завантажувачів 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=Коли встановлено, завантажувачі використовуватимуть електроенергію. 104 | miniloader-snapping=Повертати завантажувачі відповідно до конвеєрів. 105 | miniloader-double-recipes=Подвоює кількість інгредієнтів та результату в рецептах, щоб робити завантажувачі попарно. 106 | miniloader-lock-stack-sizes=Коли задано, завантажувачі будуть перевозити речі по одному. 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=Конфігурація розділеної смуги 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/zh-CN/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | chute-miniloader=滑道 3 | basic-miniloader=基础迷你装卸机 4 | miniloader=迷你装卸机 5 | fast-miniloader=快速迷你装卸机 6 | express-miniloader=极速迷你装卸机 7 | turbo-miniloader=音速迷你装卸机 8 | ultimate-miniloader=超音速迷你装卸机 9 | rapid-mk1-miniloader=迅速迷你装卸机 Mk1 10 | rapid-mk2-miniloader=迅速迷你装卸机 Mk2 11 | ub-ultra-fast-miniloader=超级快速迷你装卸机 12 | ub-extreme-fast-miniloader=究极快速迷你装卸机 13 | ub-ultra-express-miniloader=超级极速迷你装卸机 14 | ub-extreme-express-miniloader=究极极速迷你装卸机 15 | ub-ultimate-miniloader=终极迷你装卸机 16 | expedited-miniloader=急速迷你装卸机 17 | space-miniloader=太空迷你装卸机 18 | deep-space-miniloader=深空装卸机 19 | k-miniloader=优质迷你装卸机 20 | kr-advanced-miniloader=高级迷你装卸机 21 | kr-superior-miniloader=优质迷你装卸机 22 | nuclear-miniloader=核能迷你装卸机 23 | plutonium-miniloader=钚制迷你装卸机 24 | 25 | basic-filter-miniloader=基础筛选迷你装卸机 26 | filter-miniloader=筛选迷你装卸机 27 | fast-filter-miniloader=快速筛选迷你装卸机 28 | express-filter-miniloader=极速筛选迷你装卸机 29 | turbo-filter-miniloader=涡轮筛选迷你装卸机 30 | ultimate-filter-miniloader=终极筛选迷你装卸机 31 | rapid-mk1-filter-miniloader=高速筛选迷你装卸机 Mk1 32 | rapid-mk2-filter-miniloader=高速筛选迷你装卸机 Mk2 33 | ub-ultra-fast-filter-miniloader=超级快速筛选迷你装卸机 34 | ub-extreme-fast-filter-miniloader=究极快速筛选迷你装卸机 35 | ub-ultra-express-filter-miniloader=超级极速筛选迷你装卸机 36 | ub-extreme-express-filter-miniloader=究极极速筛选迷你装卸机 37 | ub-ultimate-filter-miniloader=终极筛选迷你装卸机 38 | expedited-filter-miniloader=加急筛选迷你装卸机 39 | space-filter-miniloader=太空筛选迷你装卸机 40 | deep-space-filter-miniloader=太空筛选小型装卸机 41 | k-filter-miniloader=优质筛选迷你装卸机 42 | kr-advanced-filter-miniloader=高级筛选迷你装卸机 43 | kr-superior-filter-miniloader=优质筛选迷你装卸机 44 | nuclear-filter-miniloader=核能筛选迷你装卸机 45 | plutonium-filter-miniloader=钚制筛选迷你装卸机 46 | 47 | [technology-name] 48 | basic-miniloader=基础迷你装卸机 49 | miniloader=迷你装卸机 50 | fast-miniloader=快速迷你装卸机 51 | express-miniloader=极速迷你装卸机 52 | turbo-miniloader=音速迷你装卸机 53 | ultimate-miniloader=超音速迷你装卸机 54 | rapid-mk1-miniloader=迅速迷你装卸机 Mk1 55 | rapid-mk2-miniloader=迅速迷你装卸机 Mk2 56 | ub-ultra-fast-miniloader=超级快速迷你装卸机 57 | ub-extreme-fast-miniloader=究极快速迷你装卸机 58 | ub-ultra-express-miniloader=超级极速迷你装卸机 59 | ub-extreme-express-miniloader=究极极速迷你装卸机 60 | ub-ultimate-miniloader=超音速迷你装卸机 61 | expedited-miniloader=急速迷你装卸机 62 | space-miniloader=太空迷你装卸机 63 | deep-space-miniloader=深空装卸机 64 | k-miniloader=优质迷你装卸机 65 | kr-advanced-miniloader=高级迷你装卸机 66 | kr-superior-miniloader=优质迷你装卸机 67 | nuclear-miniloader=核能迷你装卸机 68 | plutonium-miniloader=钚制迷你装卸机 69 | 70 | [technology-description] 71 | basic-miniloader=基础迷你装卸机 72 | miniloader=迷你装卸机 73 | fast-miniloader=快速迷你装卸机 74 | express-miniloader=极速迷你装卸机 75 | turbo-miniloader=音速迷你装卸机 76 | ultimate-miniloader=超音速迷你装卸机 77 | rapid-mk1-miniloader=迅速迷你装卸机 Mk1 78 | rapid-mk2-miniloader=迅速迷你装卸机 Mk2 79 | ub-ultra-fast-miniloader=超级快速迷你装卸机 80 | ub-extreme-fast-miniloader=究极快速迷你装卸机 81 | ub-ultra-express-miniloader=超级极速迷你装卸机 82 | ub-extreme-express-miniloader=究极极速迷你装卸机 83 | ub-ultimate-miniloader=超音速迷你装卸机 84 | expedited-miniloader=急速迷你装卸机 85 | space-miniloader=太空迷你装卸机 86 | deep-space-miniloader=深空装卸机 87 | k-miniloader=优质迷你装卸机 88 | kr-advanced-miniloader=高级迷你装卸机 89 | kr-superior-miniloader=优质迷你装卸机 90 | nuclear-miniloader=高级迷你装卸机,使用铀供能 91 | plutonium-miniloader=更高级的迷你装卸机,使用钚供能 92 | 93 | [mod-setting-name] 94 | miniloader-enable-standard=启用标准迷你装卸机 95 | miniloader-enable-filter=启用筛选迷你装卸机 96 | miniloader-enable-chute=启用滑道 97 | miniloader-energy-usage=迷你装卸机需要耗电 98 | miniloader-snapping=吸附迷你装卸机 99 | miniloader-double-recipes=双倍配方 100 | miniloader-lock-stack-sizes=锁定堆叠大小 101 | 102 | [mod-setting-description] 103 | miniloader-energy-usage=选中后,迷你装卸机必须连接到电网。 104 | miniloader-snapping=在建造或旋转相邻的传送带时吸附迷你装卸机。 105 | miniloader-double-recipes=加倍配方的原料和产品,来成对使用地下传送带。 106 | miniloader-lock-stack-sizes=当设置为真时,迷你装卸机总是一次移动一个物品。当设置为假时,允许使用无限的堆栈大小。这将减少UPS的消耗,但会降低物品移动的连续性。 107 | 108 | [miniloader-gui] 109 | split-lane-configuration=分流器设置 110 | 111 | 112 | -------------------------------------------------------------------------------- /locale/zh-TW/miniloader.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | basic-miniloader=基礎迷你裝卸機 3 | miniloader=迷你裝載機 4 | fast-miniloader=快速迷你裝載機 5 | express-miniloader=極速迷你裝載機 6 | turbo-miniloader=神速迷你裝載機 7 | ultimate-miniloader=終極迷你裝載機 8 | rapid-mk1-miniloader=快速迷你裝卸機 Mk1 9 | rapid-mk2-miniloader=快速迷你裝卸機 Mk2 10 | ub-ultimate-miniloader=終極迷你裝載機 11 | 12 | basic-filter-miniloader=基礎智慧迷你裝卸機 13 | filter-miniloader=迷你智能裝載機 14 | fast-filter-miniloader=快速智能迷你裝載機 15 | express-filter-miniloader=極速智能迷你裝載機 16 | turbo-filter-miniloader=神速智能迷你裝載機 17 | ultimate-filter-miniloader=終極智能迷你裝載機 18 | ub-ultimate-filter-miniloader=終極智能迷你裝載機 19 | 20 | [technology-name] 21 | basic-miniloader=基礎迷你裝卸機 22 | miniloader=迷你裝載機 23 | fast-miniloader=快速迷你裝載機 24 | express-miniloader=極速迷你裝載機 25 | turbo-miniloader=神速迷你裝載機 26 | ultimate-miniloader=終極迷你裝載機 27 | rapid-mk1-miniloader=快速迷你裝卸機 Mk1 28 | rapid-mk2-miniloader=快速迷你裝卸機 Mk2 29 | ub-ultimate-miniloader=終極迷你裝載機 30 | 31 | [technology-description] 32 | basic-miniloader=基礎迷你裝卸機 33 | miniloader=研發裝卸貨物的裝載機 34 | fast-miniloader=研發裝卸貨物的快速裝載機 35 | express-miniloader=研發裝卸貨物的極速裝載機 36 | turbo-miniloader=研發裝卸貨物的神速裝載機 37 | ultimate-miniloader=研發裝卸貨物的終極裝載機 38 | rapid-mk1-miniloader=快速迷你裝卸機 Mk1 39 | rapid-mk2-miniloader=快速迷你裝卸機 Mk2 40 | ub-ultimate-miniloader=終極迷你裝載機 41 | 42 | [mod-setting-name] 43 | 44 | [mod-setting-description] 45 | 46 | [miniloader-gui] 47 | 48 | 49 | -------------------------------------------------------------------------------- /lualib/blueprint.lua: -------------------------------------------------------------------------------- 1 | local util = require("lualib.util") 2 | 3 | local M = {} 4 | 5 | local function inserters_in_position(bp_entities, starting_index) 6 | local out = {} 7 | local x = bp_entities[starting_index].position.x 8 | local y = bp_entities[starting_index].position.y 9 | for i=starting_index,#bp_entities do 10 | local ent = bp_entities[i] 11 | if ent.position.x == x and ent.position.y == y and util.is_miniloader_inserter(ent) then 12 | out[#out+1] = ent 13 | else 14 | break 15 | end 16 | end 17 | return out 18 | end 19 | 20 | local function tag_with_configuration(surface, bp_entity) 21 | local inserters = surface.find_entities_filtered{ type = "inserter", position = bp_entity.position } 22 | if not inserters[1] then return end 23 | if not global.split_lane_configuration[inserters[1].unit_number] then return end 24 | local right_lane_inserter = inserters[2] 25 | if right_lane_inserter and util.is_output_miniloader_inserter(right_lane_inserter) then 26 | bp_entity.tags = { 27 | right_lane_settings = util.capture_settings(right_lane_inserter), 28 | } 29 | end 30 | end 31 | 32 | local function find_slaves(miniloader_inserters, to_remove) 33 | for i = 2, #miniloader_inserters do 34 | local inserter = miniloader_inserters[i] 35 | to_remove[inserter.entity_number] = true 36 | end 37 | end 38 | 39 | local function remove_connections(bp_entity, to_remove_set) 40 | local connections = bp_entity.connections 41 | if not connections then 42 | return 43 | end 44 | for circuit_id, circuit_connections in pairs(connections) do 45 | if not circuit_id:find("^Cu") then -- ignore copper cables on power switch 46 | for wire_name, wire_connections in pairs(circuit_connections) do 47 | local new_wire_connections = {} 48 | for _, connection in ipairs(wire_connections) do 49 | if not to_remove_set[connection.entity_id] then 50 | new_wire_connections[#new_wire_connections+1] = connection 51 | end 52 | end 53 | if next(new_wire_connections) then 54 | circuit_connections[wire_name] = new_wire_connections 55 | else 56 | circuit_connections[wire_name] = nil 57 | end 58 | end 59 | end 60 | end 61 | end 62 | 63 | local function remove_entities(bp_entities, to_remove_set) 64 | local cnt = #bp_entities 65 | for i=1,cnt do 66 | remove_connections(bp_entities[i], to_remove_set) 67 | end 68 | 69 | local w = 1 70 | for r=1,cnt do 71 | if not to_remove_set[bp_entities[r].entity_number] then 72 | bp_entities[w] = bp_entities[r] 73 | w = w + 1 74 | end 75 | end 76 | for i=w,cnt do 77 | bp_entities[i] = nil 78 | end 79 | end 80 | 81 | function M.is_setup_bp(stack) 82 | return stack and 83 | stack.valid and 84 | stack.valid_for_read and 85 | stack.is_blueprint and 86 | stack.is_blueprint_setup() 87 | end 88 | 89 | local huge = math.huge 90 | function M.bounding_box(bp_entities) 91 | local left = math.huge 92 | local top = math.huge 93 | local right = -math.huge 94 | local bottom = -math.huge 95 | 96 | for _, e in pairs(bp_entities) do 97 | local pos = e.position 98 | if pos.x < left then left = pos.x - 0.5 end 99 | if pos.y < top then top = pos.y - 0.5 end 100 | if pos.x > right then right = pos.x + 0.5 end 101 | if pos.y > bottom then bottom = pos.y + 0.5 end 102 | end 103 | 104 | local center_x = (right + left) / 2 105 | local center_y = (bottom + top) / 2 106 | 107 | return { 108 | left_top = {x = left - center_x, y = top - center_y}, 109 | right_bottom = {x = right - center_x, y = bottom - center_y}, 110 | } 111 | end 112 | 113 | function M.get_blueprint_to_setup(player_index) 114 | local player = game.players[player_index] 115 | 116 | -- normal drag-select 117 | local blueprint_to_setup = player.blueprint_to_setup 118 | if blueprint_to_setup 119 | and blueprint_to_setup.valid_for_read 120 | and blueprint_to_setup.is_blueprint_setup() then 121 | return blueprint_to_setup 122 | end 123 | 124 | -- alt drag-select (skips configuration dialog) 125 | local cursor_stack = player.cursor_stack 126 | if cursor_stack 127 | and cursor_stack.valid_for_read 128 | and cursor_stack.is_blueprint 129 | and cursor_stack.is_blueprint_setup() then 130 | local bp = cursor_stack 131 | while bp.is_blueprint_book do 132 | bp = bp.get_inventory(defines.inventory.item_main)[bp.active_index] 133 | end 134 | return bp 135 | end 136 | 137 | -- update of existing blueprint 138 | local opened_blueprint = global.previous_opened_blueprint_for[player_index] 139 | if opened_blueprint 140 | and opened_blueprint.tick == game.tick 141 | and opened_blueprint.blueprint 142 | and opened_blueprint.blueprint.valid_for_read 143 | and opened_blueprint.blueprint.is_blueprint_setup() then 144 | return opened_blueprint.blueprint 145 | end 146 | end 147 | 148 | function M.filter_miniloaders(bp, surface) 149 | local bp_entities = bp.get_blueprint_entities() 150 | if not bp_entities then 151 | return 152 | end 153 | local to_remove = {} 154 | local i = 1 155 | while i <= #bp_entities do 156 | local ent = bp_entities[i] 157 | if util.is_miniloader_inserter(ent) then 158 | local overlapping = inserters_in_position(bp_entities, i) 159 | tag_with_configuration(surface, overlapping[1]) 160 | find_slaves(overlapping, to_remove) 161 | i = i + #overlapping 162 | else 163 | i = i + 1 164 | end 165 | end 166 | if next(to_remove) then 167 | remove_entities(bp_entities, to_remove) 168 | bp.set_blueprint_entities(bp_entities) 169 | end 170 | end 171 | 172 | return M 173 | -------------------------------------------------------------------------------- /lualib/event.lua: -------------------------------------------------------------------------------- 1 | local M = {} 2 | 3 | local event_names = {} 4 | for name, id in pairs(defines.events) do 5 | event_names[id] = name 6 | end 7 | 8 | --[[ 9 | handlers[event_id] = { [handler1] = true, [handler2] = true, ... } 10 | ]] 11 | local handlers_for = {} 12 | 13 | local function dispatch(event) 14 | for handler in pairs(handlers_for[event.name]) do 15 | handler(event) 16 | end 17 | end 18 | 19 | function M.register(events, handler) 20 | if type(events) ~= "table" then 21 | events = {events} 22 | end 23 | 24 | for _, event_id in ipairs(events) do 25 | -- debug("registering for " .. (event_names[event_id] or event_id)) 26 | local handlers = handlers_for[event_id] 27 | if not handlers then 28 | handlers = {} 29 | handlers_for[event_id] = handlers 30 | end 31 | 32 | if not next(handlers) then 33 | script.on_event(event_id, dispatch) 34 | end 35 | 36 | handlers[handler] = true 37 | end 38 | end 39 | 40 | function M.unregister(events, handler) 41 | if type(events) ~= "table" then 42 | events = {events} 43 | end 44 | 45 | for _, event_id in ipairs(events) do 46 | -- debug("unregistering for " .. (event_names[event_id] or event_id)) 47 | local handlers = handlers_for[event_id] 48 | if handlers then 49 | handlers[handler] = nil 50 | if not next(handlers) then 51 | script.on_event(event_id, nil) 52 | end 53 | end 54 | end 55 | end 56 | 57 | return M -------------------------------------------------------------------------------- /lualib/miniloader.lua: -------------------------------------------------------------------------------- 1 | local circuit = require 'circuit' 2 | local util = require 'util' 3 | 4 | local function fast_replace_loader(loader_name, existing_loader) 5 | local last_user = existing_loader.last_user 6 | local new_loader = existing_loader.surface.create_entity{ 7 | name = loader_name, 8 | position = existing_loader.position, 9 | direction = existing_loader.direction, 10 | force = existing_loader.force, 11 | fast_replace = true, 12 | spill = false, 13 | create_build_effect_smoke = false, 14 | type = existing_loader.loader_type, 15 | } 16 | new_loader.last_user = last_user 17 | return new_loader 18 | end 19 | 20 | local function create_new_loader(loader_name, inserter, orientation) 21 | local loader = inserter.surface.create_entity{ 22 | name = loader_name, 23 | position = inserter.position, 24 | direction = orientation.direction, 25 | force = inserter.force, 26 | type = orientation.type, 27 | } 28 | loader.destructible = false 29 | return loader 30 | end 31 | 32 | local function select_connected_loader(loaders) 33 | local selected_loader 34 | for _, loader in pairs(loaders) do 35 | local tl = loader.get_transport_line(1) 36 | if next(tl.output_lines) or next(tl.input_lines) then 37 | selected_loader = loader 38 | break 39 | end 40 | end 41 | if not selected_loader then 42 | selected_loader = loaders[1] 43 | end 44 | for _, loader in pairs(loaders) do 45 | if loader ~= selected_loader then 46 | loader.destroy() 47 | end 48 | end 49 | return selected_loader 50 | end 51 | 52 | local function ensure_loader(inserter, orientation) 53 | local surface = inserter.surface 54 | local position = inserter.position 55 | local loader_name = inserter.name:gsub("inserter$", "loader") 56 | local existing_loaders = util.find_miniloaders{surface=surface, position=position} 57 | local existing_loader = select_connected_loader(existing_loaders) 58 | if existing_loader then 59 | if existing_loader.name ~= loader_name then 60 | return fast_replace_loader(loader_name, existing_loader) 61 | else 62 | existing_loader.loader_type = orientation.type 63 | end 64 | else 65 | return create_new_loader(loader_name, inserter, orientation) 66 | end 67 | return existing_loader 68 | end 69 | 70 | local function create_miniloader_inserter(main_inserter, fast_replace) 71 | local new_inserter = main_inserter.surface.create_entity{ 72 | name = main_inserter.name, 73 | position = main_inserter.position, 74 | direction = main_inserter.direction, 75 | force = main_inserter.force, 76 | fast_replace = fast_replace, 77 | spill = false, 78 | create_build_effect_smoke = false, 79 | } 80 | new_inserter.last_user = main_inserter.last_user 81 | if settings.global["miniloader-lock-stack-sizes"].value then 82 | new_inserter.inserter_stack_size_override = 1 83 | end 84 | return new_inserter 85 | end 86 | 87 | local function ensure_inserters(desired_count, main_inserter) 88 | local inserter_name = main_inserter.name 89 | local surface = main_inserter.surface 90 | local position = main_inserter.position 91 | 92 | local inserters = surface.find_entities_filtered{ type = "inserter", position = position } 93 | 94 | -- remove extra inserters 95 | for i=#inserters, desired_count+1, -1 do 96 | inserters[i].destroy() 97 | inserters[i] = nil 98 | end 99 | 100 | -- replace existing inserters 101 | for i=1, #inserters do 102 | if inserters[i].name ~= inserter_name then 103 | create_miniloader_inserter(main_inserter, true) 104 | inserters[i].destroy() 105 | end 106 | end 107 | 108 | -- create missing inserters 109 | for i=#inserters+1, desired_count do 110 | create_miniloader_inserter(main_inserter, false) 111 | end 112 | 113 | -- ensure only primary inserter can be damaged 114 | -- note that order may be different after destroy + create 115 | inserters = surface.find_entities_filtered{ type = "inserter", position = position } 116 | inserters[1].destructible = true 117 | for i=2,#inserters do 118 | inserters[i].destructible = false 119 | end 120 | 121 | return inserters 122 | end 123 | 124 | local function ensure_chest(main_inserter) 125 | local chest = main_inserter.surface.find_entity("miniloader-target-chest", main_inserter.position) 126 | if not chest then 127 | chest = main_inserter.surface.create_entity{ 128 | name = "miniloader-target-chest", 129 | position = main_inserter.position, 130 | force = main_inserter.force, 131 | } 132 | chest.destructible = false 133 | end 134 | return chest 135 | end 136 | 137 | local function fixup(main_inserter, orientation, tags) 138 | if not orientation then 139 | local existing_loader = util.find_miniloaders{surface = main_inserter.surface, position = main_inserter.position}[1] 140 | if existing_loader then 141 | orientation = {direction = existing_loader.direction, type = existing_loader.loader_type} 142 | else 143 | orientation = {direction = util.opposite_direction(main_inserter.direction), type = "input"} 144 | end 145 | end 146 | local loader = ensure_loader(main_inserter, orientation) 147 | local inserters = ensure_inserters(util.num_inserters(loader), main_inserter) 148 | circuit.copy_inserter_settings(main_inserter, inserters[1]) 149 | ensure_chest(main_inserter) 150 | 151 | util.update_inserters(loader) 152 | if tags and tags.right_lane_settings then 153 | global.split_lane_configuration[inserters[1].unit_number] = true 154 | util.apply_settings(tags.right_lane_settings, inserters[2]) 155 | end 156 | circuit.sync_behavior(main_inserter) 157 | circuit.sync_filters(main_inserter) 158 | circuit.sync_partner_connections(main_inserter) 159 | 160 | return loader 161 | end 162 | 163 | local function forall(f) 164 | for _, surface in pairs(game.surfaces) do 165 | local miniloaders = util.find_miniloaders{surface = surface} 166 | for _, entity in pairs(miniloaders) do 167 | if entity.valid then 168 | f(surface, entity) 169 | end 170 | end 171 | end 172 | end 173 | 174 | return { 175 | fixup = fixup, 176 | forall = forall, 177 | } 178 | -------------------------------------------------------------------------------- /lualib/ontick.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Utilities for managing the on_tick event, periodically invoking 3 | handlers. 4 | ]] 5 | 6 | local event = require "lualib.event" 7 | 8 | local M = {} 9 | 10 | local on_tick_handlers = {} 11 | local function on_tick_meta_handler(e) 12 | for handler, interval in pairs(on_tick_handlers) do 13 | if e.tick % interval == 0 then 14 | handler(e) 15 | end 16 | end 17 | end 18 | 19 | function M.register(f, interval) 20 | if not interval then 21 | interval = 12 22 | end 23 | if interval < 0 then 24 | error("invalid interval") 25 | end 26 | on_tick_handlers[f] = interval 27 | event.register(defines.events.on_tick, on_tick_meta_handler) 28 | end 29 | 30 | function M.unregister(f) 31 | on_tick_handlers[f] = nil 32 | if not next(on_tick_handlers) then 33 | event.unregister(defines.events.on_tick, on_tick_meta_handler) 34 | end 35 | end 36 | 37 | return M 38 | -------------------------------------------------------------------------------- /lualib/onwireplaced.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | Wires can be placed in the following ways: 3 | 4 | 1) player clicks with a green-wire or red-wire 5 | 2) construction robot revives a ghost 6 | 3) a mod script (e.g. Nanobots) revives a ghost 7 | 4) a player clicks with a blueprint over an existing entity 8 | 9 | Relevant events: 10 | on_selected_entity_changed: before 1 11 | on_player_cursor_stack_changed: after 1 12 | on_robot_built_entity: 2 13 | on_built_entity: 3 14 | on_pre_build: 4 15 | on_tick: after 4 16 | ]] 17 | 18 | local M = {} 19 | 20 | local blueprint = require "lualib.blueprint" 21 | local event = require "lualib.event" 22 | local util = require "lualib.util" 23 | 24 | M.on_wire_added = script.generate_event_name() 25 | M.on_wire_removed = script.generate_event_name() 26 | 27 | -- how often to poll circuit network connections when the player is holding wire over an entity 28 | local POLL_INTERVAL = 15 29 | 30 | local monitored_players 31 | 32 | --[[ 33 | CCD === CircuitConnectionDefinition 34 | 35 | selected_ccd_set_for[player_index] = { 36 | [ccd_key] = { 37 | wire = ..., 38 | target_entity = ..., 39 | source_circuit_id = ..., 40 | target_circuit_id = ... 41 | }, 42 | ... 43 | } 44 | ]] 45 | local selected_ccd_set_for 46 | 47 | local function ccd_key(ccd) 48 | --do return ccd.wire.."-"..ccd.source_circuit_id.."-"..ccd.target_circuit_id.."-"..ccd.target_entity.unit_number end 49 | return (ccd.wire - 2) 50 | + (ccd.source_circuit_id - 1) * 2 51 | + (ccd.target_circuit_id - 1) * 4 52 | + ccd.target_entity.unit_number * 8 53 | end 54 | 55 | local function ccd_set(entity) 56 | local ccds = entity.circuit_connection_definitions 57 | if not ccds then 58 | return {} 59 | end 60 | 61 | local out = {} 62 | for i=1,#ccds do 63 | out[ccd_key(ccds[i])] = ccds[i] 64 | end 65 | return out 66 | end 67 | 68 | local function diff_sets(old, new) 69 | local removed = {} 70 | for old_key, ccd in pairs(old) do 71 | if not new[old_key] then 72 | removed[#removed+1] = ccd 73 | end 74 | end 75 | 76 | local added = {} 77 | for new_key, ccd in pairs(new) do 78 | if not old[new_key] then 79 | added[#added+1] = ccd 80 | end 81 | end 82 | return removed, added 83 | end 84 | 85 | local function raise_on_wire_added(entity, ccd) 86 | local ev = { 87 | entity = entity, 88 | wire = ccd.wire, 89 | target_entity = ccd.target_entity, 90 | source_circuit_id = ccd.source_circuit_id, 91 | target_circuit_id = ccd.target_circuit_id, 92 | } 93 | script.raise_event(M.on_wire_added, ev) 94 | end 95 | 96 | local function raise_on_wire_removed(entity, ccd) 97 | local ev = { 98 | entity = entity, 99 | wire = ccd.wire, 100 | target_entity = ccd.target_entity, 101 | source_circuit_id = ccd.source_circuit_id, 102 | target_circuit_id = ccd.target_circuit_id, 103 | } 104 | script.raise_event(M.on_wire_removed, ev) 105 | end 106 | 107 | local function check_for_circuit_changes(entity, old, new) 108 | if not old or not new then 109 | return 110 | end 111 | 112 | local removed, added = diff_sets(old, new) 113 | for _, ccd in ipairs(removed) do 114 | raise_on_wire_removed(entity, ccd) 115 | end 116 | for _, ccd in ipairs(added) do 117 | raise_on_wire_added(entity, ccd) 118 | end 119 | end 120 | 121 | local function check_selection_for_player(player_index) 122 | local selected = game.players[player_index].selected 123 | if selected and selected.valid then 124 | local new = ccd_set(selected) 125 | check_for_circuit_changes(selected, selected_ccd_set_for[player_index], new) 126 | selected_ccd_set_for[player_index] = new 127 | end 128 | end 129 | 130 | local function check_selection_for_all(ev) 131 | if ev.tick % POLL_INTERVAL ~= 0 then 132 | return 133 | end 134 | 135 | -- check only players who we believe to have a selected entity 136 | for player_index in pairs(selected_ccd_set_for) do 137 | check_selection_for_player(player_index) 138 | end 139 | end 140 | 141 | local function start_monitoring_selected_entity(player_index) 142 | local selected = game.players[player_index].selected 143 | if selected then 144 | selected_ccd_set_for[player_index] = ccd_set(selected) 145 | event.register(defines.events.on_tick, check_selection_for_all) 146 | return 147 | end 148 | selected_ccd_set_for[player_index] = nil 149 | if not next(selected_ccd_set_for) then 150 | event.unregister(defines.events.on_tick, check_selection_for_all) 151 | end 152 | end 153 | 154 | local function on_selected_entity_changed(ev) 155 | local player_index = ev.player_index 156 | if not monitored_players[player_index] then 157 | return 158 | end 159 | 160 | if ev.last_entity then 161 | local new = ccd_set(ev.last_entity) 162 | check_for_circuit_changes(ev.last_entity, selected_ccd_set_for[player_index], new) 163 | end 164 | 165 | start_monitoring_selected_entity(player_index) 166 | end 167 | 168 | local function stop_monitoring_player_selection(player_index) 169 | -- one last check since we will no longer be monitoring this player's selection 170 | check_selection_for_player(player_index) 171 | 172 | monitored_players[player_index] = nil 173 | if not next(monitored_players) then 174 | event.unregister(defines.events.on_selected_entity_changed, on_selected_entity_changed) 175 | end 176 | 177 | selected_ccd_set_for[player_index] = nil 178 | if not next(selected_ccd_set_for) then 179 | event.unregister(defines.events.on_tick, check_selection_for_all) 180 | end 181 | end 182 | 183 | local function start_monitoring_player_selection(player_index) 184 | monitored_players[player_index] = true 185 | start_monitoring_selected_entity(player_index) 186 | event.register(defines.events.on_selected_entity_changed, on_selected_entity_changed) 187 | end 188 | 189 | local function on_player_cursor_stack_changed(ev) 190 | local player_index = ev.player_index 191 | local cursor_stack = game.players[player_index].cursor_stack 192 | if cursor_stack.valid_for_read then 193 | local name = cursor_stack.name 194 | if name == "red-wire" or name == "green-wire" then 195 | if monitored_players[player_index] then 196 | -- already monitoring, probably placed a wire 197 | check_selection_for_player(player_index) 198 | else 199 | start_monitoring_player_selection(player_index) 200 | end 201 | return 202 | end 203 | end 204 | stop_monitoring_player_selection(player_index) 205 | end 206 | 207 | local function on_built_entity(ev) 208 | local entity = ev.created_entity or ev.entity or ev.destination 209 | if not entity.valid then return end 210 | local ccds = entity.circuit_connection_definitions or {} 211 | for _, ccd in ipairs(ccds) do 212 | raise_on_wire_added(entity, ccd) 213 | end 214 | end 215 | 216 | local function on_entity_mined(ev) 217 | local entity = ev.entity 218 | if entity.valid then 219 | for _, ccd in ipairs(entity.circuit_connection_definitions or {}) do 220 | raise_on_wire_removed(entity, ccd) 221 | end 222 | end 223 | end 224 | 225 | local bp_overplace 226 | 227 | local function check_after_blueprint_placed() 228 | for unit_number, data in pairs(bp_overplace) do 229 | local entity = data.entity 230 | -- any of the entities may have become invalid due to other scripting 231 | if entity.valid then 232 | local new = ccd_set(entity) 233 | check_for_circuit_changes(entity, data.before_ccd_set, new) 234 | end 235 | bp_overplace[unit_number] = nil 236 | end 237 | 238 | event.unregister(defines.events.on_tick, check_after_blueprint_placed) 239 | end 240 | 241 | local function setup_after_blueprint_placed(preexisting_entities) 242 | for i=1,#preexisting_entities do 243 | local entity = preexisting_entities[i] 244 | if entity.unit_number then 245 | bp_overplace[entity.unit_number] = { 246 | entity = entity, 247 | before_ccd_set = ccd_set(entity), 248 | } 249 | end 250 | end 251 | 252 | event.register(defines.events.on_tick, check_after_blueprint_placed) 253 | end 254 | 255 | local function on_pre_build(ev) 256 | local player = game.players[ev.player_index] 257 | local bp_entities = player.get_blueprint_entities() 258 | if not bp_entities or not next(bp_entities) then return end 259 | local bp = player.cursor_stack 260 | local bp_area = blueprint.bounding_box(bp_entities) 261 | local surface_area = util.expand_box( 262 | util.move_box( 263 | util.rotate_box(bp_area, ev.direction), 264 | ev.position 265 | ), 266 | 1 267 | ) 268 | local preexisting_entities = player.surface.find_entities(surface_area) 269 | -- check again at the end of this tick, after blueprint has been placed 270 | setup_after_blueprint_placed(preexisting_entities) 271 | end 272 | 273 | function M.on_init() 274 | global.onwireplaced = { 275 | monitored_players = {}, 276 | selected_ccd_set_for = {}, 277 | bp_overplace = {}, 278 | } 279 | M.on_load() 280 | end 281 | 282 | function M.on_load() 283 | if not global.onwireplaced then 284 | return -- expect on_configuration_changed to be called 285 | end 286 | 287 | if global.onwireplaced.monitored_players then 288 | monitored_players = global.onwireplaced.monitored_players 289 | if next(monitored_players) then 290 | event.register(defines.events.on_selected_entity_changed, on_selected_entity_changed) 291 | end 292 | end 293 | 294 | if global.onwireplaced.selected_ccd_set_for then 295 | selected_ccd_set_for = global.onwireplaced.selected_ccd_set_for 296 | if next(selected_ccd_set_for) then 297 | event.register(defines.events.on_tick, check_selection_for_all) 298 | end 299 | end 300 | 301 | if global.onwireplaced.bp_overplace then 302 | bp_overplace = global.onwireplaced.bp_overplace 303 | if next(bp_overplace) then 304 | event.register(defines.events.on_tick, check_after_blueprint_placed) 305 | end 306 | end 307 | 308 | event.register(defines.events.on_player_cursor_stack_changed, on_player_cursor_stack_changed) 309 | event.register( 310 | { 311 | defines.events.on_built_entity, 312 | defines.events.on_entity_cloned, 313 | defines.events.on_robot_built_entity, 314 | defines.events.script_raised_built, 315 | defines.events.script_raised_revive, 316 | }, 317 | on_built_entity 318 | ) 319 | event.register( 320 | { 321 | defines.events.on_entity_died, 322 | defines.events.on_player_mined_entity, 323 | defines.events.on_robot_mined_entity, 324 | defines.events.script_raised_destroy, 325 | }, 326 | on_entity_mined 327 | ) 328 | event.register(defines.events.on_pre_build, on_pre_build) 329 | end 330 | 331 | function M.on_configuration_changed() 332 | if not global.onwireplaced then 333 | global.onwireplaced = { 334 | monitored_players = global.monitored_players or {}, 335 | selected_ccd_set_for = global.selected_ccd_set_for or {}, 336 | bp_overplace = {}, 337 | } 338 | global.monitored_players = nil 339 | global.selected_ccd_set_for = nil 340 | end 341 | M.on_load() 342 | end 343 | 344 | return M 345 | -------------------------------------------------------------------------------- /lualib/util.lua: -------------------------------------------------------------------------------- 1 | local util = {} 2 | 3 | -- Position adjustments 4 | 5 | function util.moveposition(position, offset) 6 | return {x=position.x + offset.x, y=position.y + offset.y} 7 | end 8 | 9 | function util.offset(direction, longitudinal, orthogonal) 10 | if direction == defines.direction.north then 11 | return {x=orthogonal, y=-longitudinal} 12 | end 13 | 14 | if direction == defines.direction.south then 15 | return {x=-orthogonal, y=longitudinal} 16 | end 17 | 18 | if direction == defines.direction.east then 19 | return {x=longitudinal, y=orthogonal} 20 | end 21 | 22 | if direction == defines.direction.west then 23 | return {x=-longitudinal, y=-orthogonal} 24 | end 25 | end 26 | 27 | -- BoundingBox utilities 28 | 29 | --[[ 30 | +----------------------+ 31 | | | 32 | | | 33 | | | 34 | | O | 35 | | | 36 | +----------------------+ 37 | ]] 38 | function util.rotate_box(box, direction) 39 | local left = box.left_top.x 40 | local top = box.left_top.y 41 | local right = box.right_bottom.x 42 | local bottom = box.right_bottom.y 43 | 44 | if direction == defines.direction.north then 45 | return box 46 | elseif direction == defines.direction.east then 47 | -- 90 degree rotation 48 | return { 49 | left_top = {x=-bottom, y=left}, 50 | right_bottom = {x=-top, y=right}, 51 | } 52 | elseif direction == defines.direction.south then 53 | -- 180 degree rotation 54 | return { 55 | left_top = {x=-right, y=-bottom}, 56 | right_bottom = {x=-left, y=-top}, 57 | } 58 | elseif direction == defines.direction.west then 59 | -- 270 degree rotation 60 | return { 61 | left_top = {x=top, y=-right}, 62 | right_bottom = {x=bottom, y=-left}, 63 | } 64 | else 65 | error('invalid direction passed to rotate_box') 66 | end 67 | end 68 | 69 | function util.move_box(box, offset) 70 | return { 71 | left_top = util.moveposition(box.left_top, offset), 72 | right_bottom = util.moveposition(box.right_bottom, offset), 73 | } 74 | end 75 | 76 | function util.expand_box(box, size) 77 | return { 78 | left_top = { x = box.left_top.x - size, y = box.left_top.y - size }, 79 | right_bottom = { x = box.right_bottom.x + size, y = box.right_bottom.y + size }, 80 | } 81 | end 82 | 83 | function util.entity_key(entity) 84 | return entity.surface.name.."@"..entity.position.x..","..entity.position.y 85 | end 86 | 87 | -- Direction utilities 88 | 89 | function util.is_ns(direction) 90 | return direction == 0 or direction == 4 91 | end 92 | 93 | function util.is_ew(direction) 94 | return direction == 2 or direction == 6 95 | end 96 | 97 | function util.opposite_direction(direction) 98 | if direction >= 4 then 99 | return direction - 4 100 | end 101 | return direction + 4 102 | end 103 | 104 | -- orientation utilities 105 | 106 | -- hood_side returns the "back" or hood side of a loader or underground belt 107 | function util.hood_side(entity) 108 | if entity.type == "loader-1x1" and entity.loader_type == "output" then 109 | return util.opposite_direction(entity.direction) 110 | end 111 | if entity.type == "underground-belt" and entity.belt_to_ground_type == "output" then 112 | return util.opposite_direction(entity.direction) 113 | end 114 | return entity.direction 115 | end 116 | 117 | -- belt_side returns the "front" side of a loader or underground belt 118 | function util.belt_side(entity) 119 | if entity.type == "loader-1x1" and entity.loader_type == "input" then 120 | return util.opposite_direction(entity.direction) 121 | end 122 | if entity.type == "underground-belt" and entity.belt_to_ground_type == "input" then 123 | return util.opposite_direction(entity.direction) 124 | end 125 | return entity.direction 126 | end 127 | 128 | -- miniloader utilities 129 | 130 | function util.find_miniloaders(params) 131 | params.type = "loader-1x1" 132 | local entities = params.surface.find_entities_filtered(params) 133 | local out = {} 134 | for i=1,#entities do 135 | local ent = entities[i] 136 | if util.is_miniloader(ent) then 137 | out[#out+1] = ent 138 | end 139 | end 140 | return out 141 | end 142 | 143 | function util.is_miniloader(entity) 144 | return string.find(entity.name, "miniloader%-loader$") ~= nil 145 | end 146 | 147 | function util.is_miniloader_inserter(entity) 148 | return util.is_miniloader_inserter_name(entity.name) 149 | end 150 | 151 | function util.is_miniloader_inserter_name(name) 152 | return name:find("miniloader%-inserter$") ~= nil 153 | end 154 | 155 | function util.is_output_miniloader_inserter(inserter) 156 | local orientation = util.orientation_from_inserter(inserter) 157 | return orientation and orientation.type == "output" 158 | end 159 | 160 | -- 60 items/second / 60 ticks/second / 8 items/tile = X tiles/tick 161 | local BELT_SPEED_FOR_60_PER_SECOND = 60/60/8 162 | function util.num_inserters(entity) 163 | return math.ceil(entity.prototype.belt_speed / BELT_SPEED_FOR_60_PER_SECOND) * 2 164 | end 165 | 166 | function util.pickup_position(entity) 167 | if entity.loader_type == "output" then 168 | return util.moveposition(entity.position, util.offset(entity.direction, -0.8, 0)) 169 | end 170 | return util.moveposition(entity.position, util.offset(entity.direction, -0.2, 0)) 171 | end 172 | 173 | local moveposition = util.moveposition 174 | local offset = util.offset 175 | -- drop positions for input (belt->chest) = { 0.7, +-0.25}, { 0.9, +-0.25}, {1.1, +-0.25}, {1.3, +-0.25} 176 | -- drop positions for output (chest->belt) = {-0.2, +-0.25}, {-0.0, +-0.25}, {0.1, +-0.25}, {0.3, +-0.25} 177 | function util.drop_positions(entity) 178 | local base_offset = 1.2 179 | if entity.loader_type == "output" then 180 | base_offset = base_offset - 1 181 | end 182 | local out = {} 183 | local dir = entity.direction 184 | local p1 = moveposition(entity.position, offset(dir, base_offset, -0.25)) 185 | local p2 = moveposition(p1, offset(dir, 0, 0.5)) 186 | out[1] = p1 187 | out[2] = p2 188 | for i=1,3 do 189 | local j = i * 2 + 1 190 | out[j ] = moveposition(p1, offset(dir, -0.20*i, 0)) 191 | out[j+1] = moveposition(p2, offset(dir, -0.20*i, 0)) 192 | end 193 | for i=0,3 do 194 | local j = i * 2 + 9 195 | out[j ] = moveposition(p1, offset(dir, -0.20*i, 0)) 196 | out[j+1] = moveposition(p2, offset(dir, -0.20*i, 0)) 197 | end 198 | return out 199 | end 200 | 201 | function util.get_loader_inserters(entity) 202 | local out = {} 203 | for _, e in pairs(entity.surface.find_entities_filtered{ 204 | position = entity.position, 205 | type = "inserter", 206 | }) do 207 | if util.is_miniloader_inserter(e) then 208 | out[#out+1] = e 209 | end 210 | end 211 | return out 212 | end 213 | 214 | local function update_miniloader_ghost(ghost, direction, type) 215 | local position = ghost.position 216 | -- We should normally destroy the ghost and recreate it facing the right direction, 217 | -- but destroying an entity during its on_built_entity handler makes for compatibility 218 | -- headaches. 219 | 220 | -- add offset within tile to inform orientation_from_inserters that this ghost is preconfigured 221 | if type == "input" then 222 | ghost.pickup_position = moveposition(position, offset(direction, 0.25, 0.25)) 223 | ghost.drop_position = moveposition(position, offset(direction, 1, 0.25)) 224 | else 225 | ghost.pickup_position = moveposition(position, offset(direction, -1, 0.25)) 226 | ghost.drop_position = moveposition(position, offset(direction, 0.25, 0.25)) 227 | end 228 | end 229 | 230 | function util.update_miniloader(entity, direction, type) 231 | if entity.type == "entity-ghost" and entity.ghost_type == "inserter" then 232 | return update_miniloader_ghost(entity, direction, type) 233 | end 234 | if entity.loader_type ~= type then 235 | entity.rotate() 236 | end 237 | entity.direction = direction 238 | util.update_inserters(entity) 239 | end 240 | 241 | local function dump_miniloader(entity) 242 | local inserters = util.get_loader_inserters(entity) 243 | local info = {} 244 | for _, inserter in ipairs(inserters) do 245 | info[#info+1] = inserter.unit_number..":"..serpent.line(inserter.get_or_create_control_behavior().circuit_condition) 246 | end 247 | return table.concat(info, "; ") 248 | end 249 | 250 | function util.update_inserters(entity) 251 | local inserters = util.get_loader_inserters(entity) 252 | local pickup = util.pickup_position(entity) 253 | local drop = util.drop_positions(entity) 254 | local direction = entity.direction 255 | local loader_type = entity.loader_type 256 | if loader_type == "input" then 257 | direction = util.opposite_direction(direction) 258 | end 259 | 260 | for i=#inserters,1,-1 do 261 | inserters[i].direction = direction 262 | inserters[i].pickup_position = pickup 263 | inserters[i].drop_position = drop[i] 264 | if loader_type == "input" then 265 | inserters[i].pickup_target = entity 266 | else 267 | inserters[i].drop_target = entity 268 | end 269 | end 270 | end 271 | 272 | function util.select_main_inserter(surface, position) 273 | local inserters = surface.find_entities_filtered{type = "inserter", position = position} 274 | if not next(inserters) then 275 | inserters = surface.find_entities_filtered{ghost_type = "inserter", position = position} 276 | end 277 | 278 | if not next(inserters) then return nil end 279 | for _, inserter in ipairs(inserters) do 280 | if inserter.pickup_target == nil and inserter.drop_target == nil then 281 | return inserter 282 | end 283 | end 284 | return inserters[1] 285 | end 286 | 287 | function util.orientation_from_bp_inserter(bp_inserter) 288 | local position_x = bp_inserter.position.x 289 | local position_y = bp_inserter.position.y 290 | local drop_position_x = bp_inserter.drop_position.x + position_x 291 | local drop_position_y = bp_inserter.drop_position.y + position_y 292 | local pickup_position_x = bp_inserter.pickup_position.x + position_x 293 | local pickup_position_y = bp_inserter.pickup_position.y + position_y 294 | if drop_position_x == position_x or drop_position_y == position_y then 295 | return nil -- freshly placed with no inherited positions 296 | elseif drop_position_x > position_x + 0.5 then 297 | return {direction=defines.direction.east, type="input"} 298 | elseif drop_position_x < position_x - 0.5 then 299 | return {direction=defines.direction.west, type="input"} 300 | elseif drop_position_y > position_y + 0.5 then 301 | return {direction=defines.direction.south, type="input"} 302 | elseif drop_position_y < position_y - 0.5 then 303 | return {direction=defines.direction.north, type="input"} 304 | elseif pickup_position_x > position_x + 0.5 then 305 | return {direction=defines.direction.west, type="output"} 306 | elseif pickup_position_x < position_x - 0.5 then 307 | return {direction=defines.direction.east, type="output"} 308 | elseif pickup_position_y > position_y + 0.5 then 309 | return {direction=defines.direction.north, type="output"} 310 | elseif pickup_position_y < position_y - 0.5 then 311 | return {direction=defines.direction.south, type="output"} 312 | end 313 | end 314 | 315 | function util.orientation_from_inserter(inserter) 316 | if inserter.drop_position.x == inserter.position.x and inserter.drop_position.y == inserter.position.y then 317 | return nil -- freshly placed with no inherited positions 318 | elseif inserter.drop_position.x > inserter.position.x + 0.5 then 319 | return {direction=defines.direction.east, type="input"} 320 | elseif inserter.drop_position.x < inserter.position.x - 0.5 then 321 | return {direction=defines.direction.west, type="input"} 322 | elseif inserter.drop_position.y > inserter.position.y + 0.5 then 323 | return {direction=defines.direction.south, type="input"} 324 | elseif inserter.drop_position.y < inserter.position.y - 0.5 then 325 | return {direction=defines.direction.north, type="input"} 326 | elseif inserter.pickup_position.x > inserter.position.x + 0.5 then 327 | return {direction=defines.direction.west, type="output", is_secondary=inserter.drop_position.y < inserter.position.y} 328 | elseif inserter.pickup_position.x < inserter.position.x - 0.5 then 329 | return {direction=defines.direction.east, type="output", is_secondary=inserter.drop_position.y > inserter.position.y} 330 | elseif inserter.pickup_position.y > inserter.position.y + 0.5 then 331 | return {direction=defines.direction.north, type="output", is_secondary=inserter.drop_position.x > inserter.position.x} 332 | elseif inserter.pickup_position.y < inserter.position.y - 0.5 then 333 | return {direction=defines.direction.south, type="output", is_secondary=inserter.drop_position.x < inserter.position.x} 334 | end 335 | end 336 | 337 | function util.orientation_from_inserters(entity) 338 | local inserter = util.select_main_inserter(entity.surface, entity.position) 339 | return util.orientation_from_inserter(inserter) 340 | end 341 | 342 | function util.rebuild_belt(entity) 343 | local surface = entity.surface 344 | local name = entity.name 345 | local protos = game.get_filtered_entity_prototypes{{filter="type", type=entity.type}} 346 | local temporary_replacement 347 | for proto_name in pairs(protos) do 348 | if proto_name ~= name and proto_name ~= "__self" then 349 | temporary_replacement = proto_name 350 | break 351 | end 352 | end 353 | if not temporary_replacement then return false end 354 | 355 | local last_user = entity.last_user 356 | local params = { 357 | name = temporary_replacement, 358 | position = entity.position, 359 | direction = entity.direction, 360 | force = entity.force, 361 | fast_replace = true, 362 | spill = false, 363 | create_build_effect_smoke = false, 364 | type = entity.type:find("loader") and entity.loader_type 365 | or entity.type == "underground-belt" and entity.belt_to_ground_type, 366 | } 367 | 368 | surface.create_entity(params) 369 | params.name = name 370 | local belt = surface.create_entity(params) 371 | 372 | if belt then 373 | belt.last_user = last_user 374 | return true 375 | else 376 | return false 377 | end 378 | end 379 | 380 | local control_behavior_keys = { 381 | "circuit_condition", "logistic_condition", "connect_to_logistic_network", 382 | "circuit_read_hand_contents", "circuit_mode_of_operation", "circuit_hand_read_mode", "circuit_set_stack_size", "circuit_stack_control_signal", 383 | } 384 | 385 | function util.capture_settings(ghost) 386 | local control_behavior = ghost.get_or_create_control_behavior() 387 | local control_behavior_state = {} 388 | for _, key in pairs(control_behavior_keys) do 389 | control_behavior_state[key] = control_behavior[key] 390 | end 391 | 392 | local filters = {} 393 | for i=1,ghost.filter_slot_count do 394 | filters[i] = ghost.get_filter(i) 395 | end 396 | 397 | return { 398 | control_behavior = control_behavior_state, 399 | filters = filters, 400 | } 401 | end 402 | 403 | function util.apply_settings(settings, inserter) 404 | local limit = math.min(inserter.filter_slot_count, #settings.filters) 405 | for i = 1, limit do 406 | inserter.set_filter(i, settings.filters[i]) 407 | end 408 | local control_behavior = inserter.get_or_create_control_behavior() 409 | for k, v in pairs(settings.control_behavior) do 410 | control_behavior[k] = v 411 | end 412 | end 413 | 414 | 415 | return util 416 | -------------------------------------------------------------------------------- /pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ZIP='7z' 4 | 5 | function canon_name() { 6 | dir="$(realpath "$(dirname "$0")")" 7 | 8 | parse_info() { 9 | v=`grep \"$1\" "$dir"/info.json | head -1` 10 | v="${v%%\",}" 11 | v="${v##*\"}" 12 | echo $v 13 | } 14 | 15 | name=`parse_info name` 16 | version=`parse_info version` 17 | echo "${name}_${version}" 18 | } 19 | 20 | 21 | moddir="$(realpath $(dirname "$0"))" 22 | tmpdir=$(mktemp -d) 23 | canon_name="$(canon_name)" 24 | zipfile="$PWD/$canon_name.zip" 25 | ln -nsf "$moddir" "$tmpdir/$canon_name" 26 | cd "$tmpdir" 27 | 28 | include=$( 29 | cat <<- END 30 | $canon_name/LICENSE 31 | $canon_name/changelog.txt 32 | $canon_name/info.json 33 | $canon_name/thumbnail.png 34 | $canon_name/*.lua 35 | $canon_name/*.md 36 | END 37 | ) 38 | 39 | 40 | dirs=$(ls -d "$canon_name"/*/ | grep -vF "$canon_name/$canon_name" | grep -vF resources) 41 | 42 | echo "Zipping to $zipfile:" 43 | for f in $include $dirs 44 | do 45 | echo $f 46 | done 47 | echo 48 | 49 | "$ZIP" a "$zipfile" $include $dirs 50 | -------------------------------------------------------------------------------- /prototypes/entities.lua: -------------------------------------------------------------------------------- 1 | local empty_sheet = { 2 | filename = "__core__/graphics/empty.png", 3 | priority = "very-low", 4 | width = 1, 5 | height = 1, 6 | frame_count = 1, 7 | } 8 | 9 | data:extend{ 10 | { 11 | name = "miniloader-target-chest", 12 | type = "container", 13 | flags = {"player-creation"}, 14 | collision_box = {{-0.1,-0.1},{0.1,0.1}}, 15 | collision_mask = {}, 16 | inventory_size = 0, 17 | picture = empty_sheet, 18 | }, 19 | } 20 | 21 | local function create_loaders(prefix, base_underground_name, tint) 22 | local loader_name = prefix .. "miniloader" 23 | local filter_loader_name = prefix .. "filter-miniloader" 24 | local name = loader_name .. "-loader" 25 | 26 | local entity = util.table.deepcopy(data.raw["underground-belt"][base_underground_name]) 27 | entity.type = "loader-1x1" 28 | entity.name = name 29 | entity.icons = nil 30 | entity.flags = {"player-creation"} 31 | entity.localised_name = {"entity-name." .. loader_name} 32 | entity.minable = nil 33 | entity.collision_box = {{-0.3, -0.3}, {0.3, 0.3}} 34 | entity.collision_mask = {"transport-belt-layer"} 35 | entity.selection_box = {{0, 0}, {0, 0}} 36 | entity.filter_count = 0 37 | entity.fast_replaceable_group = "loader" 38 | entity.structure = { 39 | direction_in = { 40 | sheets = { 41 | -- Base 42 | { 43 | filename = "__miniloader__/graphics/entity/miniloader-structure-base.png", 44 | width = 96, 45 | height = 96, 46 | y = 0, 47 | hr_version = { 48 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-base.png", 49 | height = 192, 50 | priority = "extra-high", 51 | scale = 0.5, 52 | width = 192, 53 | y = 0 54 | } 55 | }, 56 | -- Mask 57 | { 58 | filename = "__miniloader__/graphics/entity/miniloader-structure-mask.png", 59 | width = 96, 60 | height = 96, 61 | y = 0, 62 | tint = tint, 63 | hr_version = { 64 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-mask.png", 65 | height = 192, 66 | priority = "extra-high", 67 | scale = 0.5, 68 | width = 192, 69 | y = 0, 70 | tint = tint, 71 | } 72 | }, 73 | -- Shadow 74 | { 75 | filename = "__miniloader__/graphics/entity/miniloader-structure-shadow.png", 76 | draw_as_shadow = true, 77 | width = 96, 78 | height = 96, 79 | y = 0, 80 | hr_version = { 81 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-shadow.png", 82 | draw_as_shadow = true, 83 | height = 192, 84 | priority = "extra-high", 85 | scale = 0.5, 86 | width = 192, 87 | y = 0, 88 | } 89 | } 90 | } 91 | }, 92 | direction_out = { 93 | sheets = { 94 | -- Base 95 | { 96 | filename = "__miniloader__/graphics/entity/miniloader-structure-base.png", 97 | width = 96, 98 | height = 96, 99 | y = 96, 100 | hr_version = { 101 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-base.png", 102 | height = 192, 103 | priority = "extra-high", 104 | scale = 0.5, 105 | width = 192, 106 | y = 192 107 | } 108 | }, 109 | -- Mask 110 | { 111 | filename = "__miniloader__/graphics/entity/miniloader-structure-mask.png", 112 | width = 96, 113 | height = 96, 114 | y = 96, 115 | tint = tint, 116 | hr_version = { 117 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-mask.png", 118 | height = 192, 119 | priority = "extra-high", 120 | scale = 0.5, 121 | width = 192, 122 | y = 192, 123 | tint = tint 124 | } 125 | }, 126 | -- Shadow 127 | { 128 | filename = "__miniloader__/graphics/entity/miniloader-structure-shadow.png", 129 | width = 96, 130 | height = 96, 131 | y = 96, 132 | draw_as_shadow = true, 133 | hr_version = { 134 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-shadow.png", 135 | height = 192, 136 | priority = "extra-high", 137 | scale = 0.5, 138 | width = 192, 139 | y = 192, 140 | draw_as_shadow = true, 141 | } 142 | } 143 | } 144 | }, 145 | back_patch = { 146 | sheet = { 147 | filename = "__miniloader__/graphics/entity/miniloader-structure-back-patch.png", 148 | priority = "extra-high", 149 | width = 96, 150 | height = 96, 151 | hr_version = { 152 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-back-patch.png", 153 | priority = "extra-high", 154 | width = 192, 155 | height = 192, 156 | scale = 0.5 157 | } 158 | } 159 | }, 160 | front_patch = { 161 | sheet = { 162 | filename = "__miniloader__/graphics/entity/miniloader-structure-front-patch.png", 163 | priority = "extra-high", 164 | width = 96, 165 | height = 96, 166 | hr_version = { 167 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-front-patch.png", 168 | priority = "extra-high", 169 | width = 192, 170 | height = 192, 171 | scale = 0.5 172 | } 173 | } 174 | } 175 | } 176 | entity.container_distance = 0 177 | entity.belt_length = 0.6 178 | entity.next_upgrade = nil 179 | 180 | local filter_entity = util.table.deepcopy(entity) 181 | filter_entity.name = filter_loader_name .. "-loader" 182 | filter_entity.structure.direction_in.sheets[1].filename = "__miniloader__/graphics/entity/miniloader-filter-structure-base.png" 183 | filter_entity.structure.direction_in.sheets[1].hr_version.filename = "__miniloader__/graphics/entity/hr-miniloader-filter-structure-base.png" 184 | filter_entity.structure.direction_out.sheets[1].filename = "__miniloader__/graphics/entity/miniloader-filter-structure-base.png" 185 | filter_entity.structure.direction_out.sheets[1].hr_version.filename = "__miniloader__/graphics/entity/hr-miniloader-filter-structure-base.png" 186 | filter_entity.structure.front_patch.sheet.filename = "__miniloader__/graphics/entity/miniloader-filter-structure-front-patch.png" 187 | filter_entity.structure.front_patch.sheet.hr_version.filename = "__miniloader__/graphics/entity/hr-miniloader-filter-structure-front-patch.png" 188 | filter_entity.filter_count = 5 189 | 190 | data:extend{ 191 | entity, 192 | filter_entity, 193 | } 194 | end 195 | 196 | local connector_definitions = circuit_connector_definitions.create( 197 | universal_connector_template, 198 | { 199 | { variation = 24, main_offset = util.by_pixel(-17, 0), shadow_offset = util.by_pixel(10, -0.5), show_shadow = false }, 200 | { variation = 24, main_offset = util.by_pixel(-14, 0), shadow_offset = util.by_pixel(5, -5), show_shadow = false }, 201 | { variation = 24, main_offset = util.by_pixel(-17, 0), shadow_offset = util.by_pixel(-2.5, 6), show_shadow = false }, 202 | { variation = 31, main_offset = util.by_pixel(14, 0), shadow_offset = util.by_pixel(5, -5), show_shadow = false }, 203 | } 204 | ) 205 | 206 | local function create_inserters(prefix, next_prefix, base_underground_name, tint) 207 | local loader_name = prefix .. "miniloader" 208 | local name = loader_name .. "-inserter" 209 | local next_upgrade = next_prefix and next_prefix .. "miniloader-inserter" 210 | local filter_loader_name = prefix .. "filter-miniloader" 211 | local filter_name = filter_loader_name .. "-inserter" 212 | local filter_next_upgrade = next_prefix and next_prefix .. "filter-miniloader-inserter" 213 | local base_entity = data.raw["underground-belt"][base_underground_name] 214 | local rounded_items_per_second = math.floor(base_entity.speed * 480 * 100 + 0.5) / 100 215 | local description = {"", 216 | "[font=default-semibold][color=255,230,192]", {"description.belt-speed"}, ":[/color][/font] ", 217 | rounded_items_per_second, " ", {"description.belt-items"}, {"per-second-suffix"}} 218 | 219 | local loader_inserter = { 220 | type = "inserter", 221 | name = name, 222 | -- this name and icon appear in the power usage UI 223 | localised_name = {"entity-name." .. loader_name}, 224 | localised_description = description, 225 | icons = { 226 | { 227 | icon = "__miniloader__/graphics/item/icon-base.png", 228 | icon_size = 64, 229 | }, 230 | { 231 | icon = "__miniloader__/graphics/item/icon-mask.png", 232 | icon_size = 64, 233 | tint = tint, 234 | }, 235 | }, 236 | minable = { mining_time = 0.1, result = loader_name }, 237 | collision_box = {{-0.2, -0.2}, {0.2, 0.2}}, 238 | collision_mask = {"floor-layer", "object-layer", "water-tile", space_collision_layer}, 239 | selection_box = {{-0.5, -0.5}, {0.5, 0.5}}, 240 | selection_priority = 50, 241 | allow_custom_vectors = true, 242 | energy_per_movement = ".0000001J", 243 | energy_per_rotation = ".0000001J", 244 | energy_source = { 245 | type = "void", 246 | }, 247 | extension_speed = 1, 248 | rotation_speed = 0.5, 249 | fast_replaceable_group = "miniloader-inserter", 250 | pickup_position = {0, 0}, 251 | insert_position = {0, 0}, 252 | draw_held_item = false, 253 | draw_inserter_arrow = false, 254 | platform_picture = { 255 | sheets = { 256 | -- Base 257 | { 258 | filename = "__miniloader__/graphics/entity/miniloader-inserter-base.png", 259 | width = 96, 260 | height = 96, 261 | y = 96, 262 | hr_version = 263 | { 264 | filename = "__miniloader__/graphics/entity/hr-miniloader-inserter-base.png", 265 | height = 192, 266 | priority = "extra-high", 267 | scale = 0.5, 268 | width = 192, 269 | y = 192 270 | } 271 | }, 272 | -- Mask 273 | { 274 | filename = "__miniloader__/graphics/entity/miniloader-structure-mask.png", 275 | width = 96, 276 | height = 96, 277 | y = 96, 278 | tint = tint, 279 | hr_version = 280 | { 281 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-mask.png", 282 | height = 192, 283 | priority = "extra-high", 284 | scale = 0.5, 285 | width = 192, 286 | y = 192, 287 | tint = tint 288 | } 289 | }, 290 | -- Shadow 291 | { 292 | filename = "__miniloader__/graphics/entity/miniloader-structure-shadow.png", 293 | width = 96, 294 | height = 96, 295 | y = 96, 296 | draw_as_shadow = true, 297 | hr_version = 298 | { 299 | filename = "__miniloader__/graphics/entity/hr-miniloader-structure-shadow.png", 300 | height = 192, 301 | priority = "extra-high", 302 | scale = 0.5, 303 | width = 192, 304 | y = 192, 305 | draw_as_shadow = true, 306 | } 307 | } 308 | } 309 | }, 310 | hand_base_picture = empty_sheet, 311 | hand_open_picture = empty_sheet, 312 | hand_closed_picture = empty_sheet, 313 | circuit_wire_connection_points = connector_definitions.points, 314 | circuit_connector_sprites = connector_definitions.sprites, 315 | circuit_wire_max_distance = default_circuit_wire_max_distance, 316 | next_upgrade = next_upgrade, 317 | } 318 | 319 | --Space Exploration 320 | if (prefix == "space-") or (prefix == "deep-space-") then 321 | loader_inserter.collision_mask = {"floor-layer", "item-layer", "object-layer", "water-tile"} 322 | end 323 | 324 | if settings.startup["miniloader-energy-usage"].value then 325 | loader_inserter.energy_per_movement = "2kJ" 326 | loader_inserter.energy_per_rotation = "2kJ" 327 | loader_inserter.energy_source = { 328 | type = "electric", 329 | usage_priority = "secondary-input", 330 | } 331 | end 332 | 333 | for _,k in ipairs{"flags", "max_health", "resistances", "vehicle_impact_sound"} do 334 | loader_inserter[k] = base_entity[k] 335 | end 336 | 337 | local filter_loader_inserter = util.table.deepcopy(loader_inserter) 338 | filter_loader_inserter.name = filter_name 339 | filter_loader_inserter.localised_name = {"entity-name." .. filter_loader_name} 340 | filter_loader_inserter.icons[1].icon = "__miniloader__/graphics/item/filter-icon-base.png" 341 | filter_loader_inserter.platform_picture.sheets[1].filename = "__miniloader__/graphics/entity/miniloader-filter-inserter-base.png" 342 | filter_loader_inserter.platform_picture.sheets[1].hr_version.filename = "__miniloader__/graphics/entity/hr-miniloader-filter-inserter-base.png" 343 | filter_loader_inserter.minable.result = filter_loader_name 344 | filter_loader_inserter.filter_count = 5 345 | filter_loader_inserter.next_upgrade = filter_next_upgrade 346 | 347 | if settings.startup["miniloader-enable-standard"].value then 348 | data:extend{loader_inserter} 349 | end 350 | if settings.startup["miniloader-enable-filter"].value then 351 | data:extend{filter_loader_inserter} 352 | end 353 | end 354 | 355 | return { 356 | create_loaders = create_loaders, 357 | create_inserters = create_inserters, 358 | } -------------------------------------------------------------------------------- /prototypes/items.lua: -------------------------------------------------------------------------------- 1 | local function create_items(prefix, base_underground_name, tint) 2 | local name = prefix .. "miniloader" 3 | local filter_name = prefix .. "filter-miniloader" 4 | 5 | local item = util.table.deepcopy(data.raw.item[base_underground_name]) 6 | item.name = name 7 | item.localised_name = {"entity-name." .. name} 8 | item.icon = nil 9 | item.icons = { 10 | { 11 | icon = "__miniloader__/graphics/item/icon-base.png", 12 | icon_size = 64, 13 | }, 14 | { 15 | icon = "__miniloader__/graphics/item/icon-mask.png", 16 | icon_size = 64, 17 | tint = tint, 18 | }, 19 | } 20 | item.order, _ = string.gsub(item.order, "^b%[underground%-belt%]", "e[miniloader]", 1) 21 | item.order, _ = string.gsub(item.order, "^c%[rapid%-transport%-belt%-to%-ground.*%]", "e[miniloader]", 1) 22 | item.place_result = name .. "-inserter" 23 | 24 | local filter_item = util.table.deepcopy(item) 25 | filter_item.name = filter_name 26 | filter_item.localised_name = {"entity-name." .. filter_name} 27 | filter_item.icons[1].icon = "__miniloader__/graphics/item/filter-icon-base.png" 28 | filter_item.order, _ = string.gsub(item.order, "e%[", "f[filter-", 1) 29 | filter_item.place_result = filter_name .. "-inserter" 30 | 31 | if settings.startup["miniloader-enable-standard"].value then 32 | data:extend{item} 33 | end 34 | if settings.startup["miniloader-enable-filter"].value then 35 | data:extend{filter_item} 36 | end 37 | end 38 | 39 | return { 40 | create_items = create_items, 41 | } 42 | -------------------------------------------------------------------------------- /prototypes/recipes.lua: -------------------------------------------------------------------------------- 1 | require "util" 2 | 3 | local ingredient_sets = { 4 | -- base 5 | -- 105 I, 27 C 6 | ["miniloader"] = { 7 | { 8 | {"underground-belt", 1}, 9 | {"forging-steel", 2}, 10 | {"mechanism-1", 1}, 11 | }, 12 | { 13 | {"underground-belt", 1}, 14 | {"steel-plate", 8}, 15 | {"fast-inserter", 6}, 16 | }, 17 | }, 18 | -- 358 I, 128 C, 89 O 19 | ["fast-miniloader"] = { 20 | { 21 | {"miniloader", 1}, 22 | {"fast-underground-belt", 1}, 23 | {"gear-2", 2}, 24 | }, 25 | { 26 | {"miniloader", 1}, 27 | {"fast-underground-belt", 1}, 28 | {"stack-inserter", 4}, 29 | }, 30 | }, 31 | -- 628 I, 384 C, 174 O 32 | ["express-miniloader"] = { 33 | { 34 | {"expedited-miniloader", 1}, 35 | {"express-underground-belt", 1}, 36 | {"forging-stainless", 2}, 37 | }, 38 | { 39 | {"fast-miniloader", 1}, 40 | {"express-underground-belt", 1}, 41 | {"stack-inserter", 2}, 42 | }, 43 | }, 44 | 45 | ["chute-miniloader"] = { 46 | { 47 | {"iron-plate", 4} 48 | }, 49 | }, 50 | 51 | -- boblogistics 52 | ["basic-miniloader"] = { 53 | { 54 | {"basic-underground-belt", 1}, 55 | {"burner-inserter", 12}, 56 | }, 57 | }, 58 | ["turbo-miniloader"] = { 59 | { 60 | {"express-miniloader", 1}, 61 | {"turbo-underground-belt", 1}, 62 | {"express-stack-inserter", 4}, 63 | }, 64 | }, 65 | ["ultimate-miniloader"] = { 66 | { 67 | {"turbo-miniloader", 1}, 68 | {"ultimate-underground-belt", 1}, 69 | {"express-stack-inserter", 2}, 70 | }, 71 | }, 72 | 73 | -- FactorioExtended-Plus-Transport 74 | ["rapid-mk1-miniloader"] = { 75 | { 76 | {"express-miniloader", 1}, 77 | {"rapid-transport-belt-to-ground-mk1", 1}, 78 | {"stack-inserter-mk2", 4}, 79 | }, 80 | }, 81 | ["rapid-mk2-miniloader"] = { 82 | { 83 | {"rapid-mk1-miniloader", 1}, 84 | {"rapid-transport-belt-to-ground-mk2", 1}, 85 | {"stack-inserter-mk2", 2}, 86 | }, 87 | }, 88 | 89 | -- Krastorio 90 | ["k-miniloader"] = { 91 | { 92 | {"express-miniloader", 1}, 93 | {"k-underground-belt", 1}, 94 | {"stack-inserter", 2}, 95 | }, 96 | }, 97 | 98 | -- Krastorio2 99 | ["kr-advanced-miniloader"] = { 100 | { 101 | {"express-miniloader", 1}, 102 | {"kr-advanced-underground-belt", 1}, 103 | {"stack-inserter", 2}, 104 | }, 105 | }, 106 | ["kr-superior-miniloader"] = { 107 | { 108 | {"kr-advanced-miniloader", 1}, 109 | {"kr-superior-underground-belt", 1}, 110 | {"kr-superior-inserter", 2}, 111 | }, 112 | }, 113 | 114 | -- UltimateBelts 115 | ["ub-ultra-fast-miniloader"] = { 116 | { 117 | {"express-miniloader", 1}, 118 | {"ultra-fast-underground-belt", 1}, 119 | {"stack-inserter", 6}, 120 | }, 121 | }, 122 | ["ub-extreme-fast-miniloader"] = { 123 | { 124 | {"ub-ultra-fast-miniloader", 1}, 125 | {"extreme-fast-underground-belt", 1}, 126 | {"stack-inserter", 6}, 127 | }, 128 | }, 129 | ["ub-ultra-express-miniloader"] = { 130 | { 131 | {"ub-extreme-fast-miniloader", 1}, 132 | {"ultra-express-underground-belt", 1}, 133 | {"stack-inserter", 6}, 134 | }, 135 | }, 136 | ["ub-extreme-express-miniloader"] = { 137 | { 138 | {"ub-ultra-express-miniloader", 1}, 139 | {"extreme-express-underground-belt", 1}, 140 | {"stack-inserter", 6}, 141 | }, 142 | }, 143 | ["ub-ultimate-miniloader"] = { 144 | { 145 | {"ub-extreme-express-miniloader", 1}, 146 | {"original-ultimate-underground-belt", 1}, 147 | {"stack-inserter", 6}, 148 | }, 149 | }, 150 | 151 | -- xander-mod 152 | ["expedited-miniloader"] = { 153 | { 154 | {"fast-miniloader", 1}, 155 | {"expedited-underground-belt", 1}, 156 | {"mechanism-2", 1}, 157 | }, 158 | }, 159 | 160 | -- space-exploration 161 | ["space-miniloader"] = { 162 | { 163 | {"se-space-underground-belt", 1}, 164 | {"stack-inserter", 4}, 165 | }, 166 | }, 167 | ["deep-space-miniloader"] = { 168 | { 169 | {"se-deep-space-underground-belt-black", 1}, 170 | {"stack-inserter", 6}, 171 | }, 172 | }, 173 | 174 | -- Random Factorio Things 175 | ["nuclear-miniloader"] = { 176 | { 177 | {"nuclear-underground-belt", 1}, 178 | {"express-miniloader", 1}, 179 | {"nuclear-stack-inserter", 4} 180 | } 181 | }, 182 | ["plutonium-miniloader"] = { 183 | { 184 | {"plutonium-underground-belt", 1}, 185 | {"nuclear-miniloader", 1}, 186 | {"plutonium-stack-inserter", 4} 187 | } 188 | } 189 | } 190 | 191 | if data.raw["inserter"]["turbo-inserter"] then 192 | -- boblogistics inserter overhaul support 193 | ingredient_sets["miniloader"][2][3] = {"inserter", 8} 194 | ingredient_sets["fast-miniloader"][2][3] = {"long-handed-inserter", 8} 195 | ingredient_sets["express-miniloader"][2][3] = {"fast-inserter", 6} 196 | ingredient_sets["turbo-miniloader"][1][3] = {"turbo-inserter", 6} 197 | ingredient_sets["ultimate-miniloader"][1][3] = {"express-inserter", 6} 198 | end 199 | 200 | local previous_miniloader = { 201 | ["fast-"] = "", 202 | ["express-"] = "fast-", 203 | 204 | -- boblogistics 205 | ["turbo-"] = "express-", 206 | ["ultimate-"] = "turbo-", 207 | 208 | -- FactorioExtended-Plus-Transport 209 | ["rapid-mk1-"] = "express-", 210 | ["rapid-mk2-"] = "rapid-mk1-", 211 | 212 | -- Krastorio 213 | ["k-"] = "express-", 214 | 215 | -- Krastorio2 216 | ["kr-advanced-"] = "express-", 217 | ["kr-superior-"] = "kr-advanced-", 218 | 219 | -- UltimateBelts 220 | ["ub-ultra-fast-"] = "express-", 221 | ["ub-extreme-fast-"] = "ub-ultra-fast-", 222 | ["ub-ultra-express-"] = "ub-extreme-fast-", 223 | ["ub-extreme-express-"] = "ub-ultra-express-", 224 | ["ub-ultimate-"] = "ub-extreme-express-", 225 | 226 | -- xander-mod 227 | ["expedited-"] = "fast-", 228 | 229 | -- Random Factorio Things 230 | ["nuclear-"] = "express-", 231 | ["plutonium"] = "nuclear-" 232 | } 233 | 234 | if data.raw["transport-belt"]["basic-transport-belt"] then 235 | table.insert(ingredient_sets["miniloader"][2], 1, {"basic-miniloader", 1}) 236 | previous_miniloader[""] = "basic-" 237 | end 238 | 239 | if data.raw.item["expedited-transport-belt"] then 240 | previous_miniloader["express-"] = "expedited-" 241 | end 242 | 243 | local filter_inserters = { 244 | ["fast-inserter"] = "filter-inserter", 245 | ["stack-inserter"] = "stack-filter-inserter", 246 | ["express-stack-inserter"] = "express-stack-filter-inserter", 247 | 248 | -- boblogistics overhaul 249 | ["inserter"] = "yellow-filter-inserter", 250 | ["long-handed-inserter"] = "red-filter-inserter", 251 | ["turbo-inserter"] = "turbo-filter-inserter", 252 | ["express-inserter"] = "express-filter-inserter", 253 | 254 | -- FactorioExtended-Plus-Transport 255 | ["stack-inserter-mk2"] = "stack-filter-inserter-mk2", 256 | 257 | -- Krastorio2 258 | ["kr-superior-inserter"] = "kr-superior-filter-inserter", 259 | 260 | -- Random Factorio Things 261 | ["nuclear-stack-inserter"] = "nuclear-stack-filter-inserter", 262 | ["plutonium-stack-inserter"] = "nuclear-stack-filter-inserter" 263 | } 264 | 265 | -- apply recipe changes due to settings 266 | local should_require_previous = true 267 | if settings.startup["bobmods-logistics-beltrequireprevious"] then 268 | should_require_previous = settings.startup["bobmods-logistics-beltrequireprevious"].value 269 | end 270 | local should_double_recipes = settings.startup["miniloader-double-recipes"].value 271 | 272 | for _, sets in pairs(ingredient_sets) do 273 | for _, set in pairs(sets) do 274 | if not should_require_previous and set[1][1]:find("miniloader$") then 275 | table.remove(set, 1) 276 | end 277 | if should_double_recipes then 278 | for _, ingredient in pairs(set) do 279 | ingredient[2] = ingredient[2] * 2 280 | end 281 | end 282 | end 283 | end 284 | 285 | local function select_ingredient_set(sets) 286 | for _, set in ipairs(sets) do 287 | local valid = true 288 | for _, ingredient in pairs(set) do 289 | if valid 290 | and not ingredient[1]:find("miniloader") 291 | and not data.raw.item[ingredient[1]] then 292 | valid = false 293 | end 294 | end 295 | if valid then 296 | return set 297 | end 298 | end 299 | end 300 | 301 | local function create_recipes(prefix) 302 | local name = prefix .. "miniloader" 303 | local filter_name = prefix .. "filter-miniloader" 304 | 305 | local recipe = { 306 | type = "recipe", 307 | name = name, 308 | enabled = false, 309 | energy_required = 1, 310 | ingredients = select_ingredient_set(ingredient_sets[name]), 311 | results = {{name, should_double_recipes and 2 or 1}}, 312 | } 313 | 314 | local filter_recipe = util.table.deepcopy(recipe) 315 | filter_recipe.name = filter_name 316 | if previous_miniloader[prefix] and data.raw.item[previous_miniloader[prefix] .. "filter-miniloader"] then 317 | filter_recipe.ingredients[1][1] = previous_miniloader[prefix] .. "filter-miniloader" 318 | end 319 | local inserter_index, inserter_name 320 | for i, ingredient in pairs(recipe.ingredients) do 321 | if ingredient[1]:find("inserter") then 322 | inserter_index = i 323 | inserter_name = ingredient[1] 324 | end 325 | end 326 | filter_recipe.results[1][1] = filter_name 327 | if inserter_name and filter_inserters[inserter_name] then 328 | filter_recipe.ingredients[inserter_index][1] = filter_inserters[inserter_name] 329 | else 330 | filter_recipe = nil 331 | end 332 | 333 | if settings.startup["miniloader-enable-standard"].value then 334 | data:extend{recipe} 335 | end 336 | if filter_recipe and settings.startup["miniloader-enable-filter"].value then 337 | data:extend{filter_recipe} 338 | end 339 | end 340 | 341 | return { 342 | create_recipes = create_recipes, 343 | } 344 | -------------------------------------------------------------------------------- /prototypes/technologies.lua: -------------------------------------------------------------------------------- 1 | require "util" 2 | 3 | local function create_technology(prefix, tech_prereqs, tint) 4 | local name = prefix .. "miniloader" 5 | local filter_name = prefix .. "filter-miniloader" 6 | 7 | local main_prereq = data.raw["technology"][tech_prereqs[1]] 8 | 9 | local effects = {} 10 | if settings.startup["miniloader-enable-standard"].value then 11 | table.insert(effects, { type = "unlock-recipe", recipe = name }) 12 | end 13 | if data.raw.recipe[filter_name] then 14 | table.insert(effects, { type = "unlock-recipe", recipe = filter_name }) 15 | end 16 | 17 | local technology = { 18 | type = "technology", 19 | name = name, 20 | icons = { 21 | { 22 | icon = "__miniloader__/graphics/technology/technology-base.png", 23 | icon_size = 128, 24 | }, 25 | { 26 | icon = "__miniloader__/graphics/technology/technology-mask.png", 27 | icon_size = 128, 28 | tint = tint, 29 | }, 30 | }, 31 | effects = effects, 32 | prerequisites = tech_prereqs, 33 | unit = util.table.deepcopy(main_prereq.unit), 34 | order = main_prereq.order 35 | } 36 | 37 | data:extend{technology} 38 | end 39 | 40 | return { 41 | create_technology = create_technology, 42 | } 43 | -------------------------------------------------------------------------------- /prototypes/templates.lua: -------------------------------------------------------------------------------- 1 | local templates = { 2 | [""] = { 3 | next_prefix = "fast-", 4 | prerequisite_techs = {"logistics", "fast-inserter", "steel-processing"}, 5 | tint = util.color("ffc340D1"), 6 | }, 7 | ["fast-"] = { 8 | next_prefix = "express-", 9 | prerequisite_techs = {"logistics-2", "miniloader"}, 10 | tint = util.color("e31717D1"), 11 | }, 12 | ["express-"] = { 13 | prerequisite_techs = {"logistics-3", "fast-miniloader"}, 14 | tint = util.color("43c0faD1"), 15 | } 16 | } 17 | 18 | -- Bob's support 19 | if data.raw.item["basic-transport-belt"] then 20 | local hex, alpha 21 | if mods["boblogistics-belt-reskin"] then 22 | basic_hex = "00000000" 23 | else 24 | basic_hex = "7d7d7dD1" 25 | end 26 | templates["basic-"] = { 27 | next_prefix = "", 28 | prerequisite_techs = {"logistics-0"}, 29 | tint = util.color(basic_hex), 30 | } 31 | templates[""].prerequisite_techs = {"logistics", "basic-miniloader"} 32 | end 33 | 34 | if data.raw.item["turbo-transport-belt"] then 35 | local turbo_hex 36 | if mods["boblogistics-belt-reskin"] then 37 | turbo_hex = "df1ee5D1" 38 | else 39 | turbo_hex = "a510e5D1" 40 | end 41 | templates["express-"].next_prefix = "turbo-" 42 | templates["turbo-"] = { 43 | next_prefix = "ultimate-", 44 | prerequisite_techs = {"logistics-4", "express-miniloader"}, 45 | tint = util.color(turbo_hex), 46 | } 47 | templates["ultimate-"] = { 48 | prerequisite_techs = {"logistics-5", "turbo-miniloader"}, 49 | tint = util.color("16f263D1"), 50 | } 51 | end 52 | 53 | -- FactorioExtended-Plus-Transport support 54 | if data.raw.item["rapid-transport-belt-mk2"] then 55 | templates["express-"].next_prefix = "rapid-mk1-" 56 | templates["rapid-mk1-"] = { 57 | next_prefix = "rapid-mk2-", 58 | prerequisite_techs = {"logistics-4", "express-miniloader"}, 59 | tint = util.color("2cd529D1"), 60 | base_underground_name = "rapid-transport-belt-to-ground-mk1", 61 | } 62 | templates["rapid-mk2-"] = { 63 | prerequisite_techs = {"logistics-5", "rapid-mk1-miniloader"}, 64 | tint = util.color("9a2cc9D1"), 65 | base_underground_name = "rapid-transport-belt-to-ground-mk2", 66 | } 67 | end 68 | 69 | -- Krastorio2 support 70 | if data.raw.item["kr-superior-transport-belt"] then 71 | templates["express-"].next_prefix = "kr-advanced-" 72 | templates["kr-advanced-"] = { 73 | prerequisite_techs = {"kr-logistic-4", "express-miniloader"}, 74 | tint = util.color("3ade21D1"), 75 | } 76 | templates["kr-superior-"] = { 77 | prerequisite_techs = {"kr-logistic-5", "kr-advanced-miniloader"}, 78 | tint = util.color("a30bd6D1"), 79 | } 80 | end 81 | 82 | -- RandomFactorioThings and PlutoniumEnergy support 83 | -- note: RFT doesn't add belts and other plutonium machinery without PE mod 84 | if mods["RandomFactorioThings"] then 85 | templates["nuclear-"] = { 86 | prerequisite_techs = {"nuclear-logistics", "express-miniloader"}, 87 | tint = util.color("00ff00") 88 | } 89 | if mods["PlutoniumEnergy"] then 90 | templates["plutonium-"] = { 91 | prerequisite_techs = {"plutonium-logistics", "nuclear-miniloader"}, 92 | tint = util.color("00e1ffde") 93 | } 94 | end 95 | end 96 | 97 | -- UltimateBelts support 98 | if data.raw.technology["ultimate-logistics"] then 99 | -- Support both sets of Ultimate Belt colors 100 | local ub_hexes = {} 101 | if mods["UltimateBelts_Owoshima_And_Pankeko-Mod"] then 102 | -- Pankeko UB colors 103 | ub_hexes.ultra_fast = "2bc24bDB" 104 | ub_hexes.extreme_fast = "c4632fDB" 105 | ub_hexes.ultra_express = "6f2de0D1" 106 | ub_hexes.extreme_express = "3d3af0DB" 107 | ub_hexes.ultimate = "999999D1" 108 | else 109 | -- Standard UB colors 110 | ub_hexes.ultra_fast = "00b30cFF" 111 | ub_hexes.extreme_fast = "e00000FF" 112 | ub_hexes.ultra_express = "3604b5E8" 113 | ub_hexes.extreme_express = "002bffFF" 114 | ub_hexes.ultimate = "00ffddD1" 115 | end 116 | 117 | -- Setup miniloaders 118 | templates["ub-ultra-fast-"] = { 119 | next_prefix = "ub-extreme-fast-", 120 | prerequisite_techs = {"ultra-fast-logistics", "express-miniloader"}, 121 | tint = util.color(ub_hexes.ultra_fast), 122 | base_underground_name = "ultra-fast-underground-belt", 123 | } 124 | templates["ub-extreme-fast-"] = { 125 | next_prefix = "ub-ultra-express-", 126 | prerequisite_techs = {"extreme-fast-logistics", "ub-ultra-fast-miniloader"}, 127 | tint = util.color(ub_hexes.extreme_fast), 128 | base_underground_name = "extreme-fast-underground-belt", 129 | } 130 | templates["ub-ultra-express-"] = { 131 | next_prefix = "ub-extreme-express-", 132 | prerequisite_techs = {"ultra-express-logistics", "ub-extreme-fast-miniloader"}, 133 | tint = util.color(ub_hexes.ultra_express), 134 | base_underground_name = "ultra-express-underground-belt", 135 | } 136 | templates["ub-extreme-express-"] = { 137 | next_prefix = "ub-ultimate-", 138 | prerequisite_techs = {"extreme-express-logistics", "ub-ultra-express-miniloader"}, 139 | tint = util.color(ub_hexes.extreme_express), 140 | base_underground_name = "extreme-express-underground-belt", 141 | } 142 | templates["ub-ultimate-"] = { 143 | prerequisite_techs = {"ultimate-logistics", "ub-extreme-express-miniloader"}, 144 | tint = util.color(ub_hexes.ultimate), 145 | base_underground_name = "original-ultimate-underground-belt", 146 | } 147 | end 148 | 149 | -- space-exploration support 150 | if data.raw.item["se-space-transport-belt"] then 151 | templates["space-"] = { 152 | prerequisite_techs = {"se-space-platform-scaffold"}, 153 | base_underground_name = "se-space-underground-belt", 154 | } 155 | end 156 | 157 | if data.raw.item["se-deep-space-transport-belt-black"] then 158 | templates["deep-space-"] = { 159 | prerequisite_techs = {"se-deep-space-transport-belt"}, 160 | tint = {r=0,g=0,b=0}, 161 | base_underground_name = "se-deep-space-underground-belt-black", 162 | } 163 | templates["space-"]["next_prefix"] = "deep-space-" 164 | end 165 | 166 | return templates 167 | -------------------------------------------------------------------------------- /resources/assemblerdemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/resources/assemblerdemo.png -------------------------------------------------------------------------------- /resources/priority_split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/resources/priority_split.png -------------------------------------------------------------------------------- /resources/rebalance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/resources/rebalance.png -------------------------------------------------------------------------------- /resources/ups_cost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/resources/ups_cost.png -------------------------------------------------------------------------------- /resources/wagon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/resources/wagon.png -------------------------------------------------------------------------------- /settings.lua: -------------------------------------------------------------------------------- 1 | data:extend{ 2 | { 3 | type = "bool-setting", 4 | name = "miniloader-energy-usage", 5 | setting_type = "startup", 6 | default_value = true, 7 | order = "miniloader-energy-usage", 8 | }, 9 | 10 | { 11 | type = "bool-setting", 12 | name = "miniloader-snapping", 13 | setting_type = "runtime-global", 14 | default_value = true, 15 | order = "miniloader-snapping", 16 | }, 17 | 18 | { 19 | type = "bool-setting", 20 | name = "miniloader-enable-standard", 21 | setting_type = "startup", 22 | default_value = true, 23 | }, 24 | 25 | { 26 | type = "bool-setting", 27 | name = "miniloader-enable-filter", 28 | setting_type = "startup", 29 | default_value = true, 30 | }, 31 | 32 | { 33 | type = "bool-setting", 34 | name = "miniloader-enable-chute", 35 | setting_type = "startup", 36 | default_value = true, 37 | }, 38 | 39 | { 40 | type = "bool-setting", 41 | name = "miniloader-double-recipes", 42 | setting_type = "startup", 43 | default_value = false, 44 | }, 45 | 46 | { 47 | type = "bool-setting", 48 | name = "miniloader-lock-stack-sizes", 49 | setting_type = "runtime-global", 50 | default_value = true, 51 | }, 52 | } -------------------------------------------------------------------------------- /snapping.lua: -------------------------------------------------------------------------------- 1 | local snapping = {} 2 | 3 | local util = require("lualib.util") 4 | 5 | local belt_types = { 6 | ["loader"] = true, 7 | ["loader-1x1"] = true, 8 | ["splitter"] = true, 9 | ["underground-belt"] = true, 10 | ["transport-belt"] = true 11 | } 12 | 13 | local function is_belt(entity) 14 | return belt_types[entity.type] or entity.type == "entity-ghost" and belt_types[entity.ghost_type] 15 | end 16 | 17 | -- set loader direction according to adjacent belts 18 | -- returns true if the loader and entity are directionally aligned 19 | local function snap_loader_to_target(loader, entity) 20 | local lx = loader.position.x 21 | local ly = loader.position.y 22 | local ldir = loader.direction 23 | 24 | local ex = entity.position.x 25 | local ey = entity.position.y 26 | local edir = entity.direction 27 | 28 | local direction 29 | local type 30 | if util.is_ns(ldir) and lx >= ex-0.6 and lx <= ex+0.6 then 31 | -- loader and entity are aligned vertically 32 | if ly > ey then -- entity to north 33 | if edir == 4 then 34 | direction = 4 35 | type = "input" 36 | else 37 | direction = 0 38 | type = "output" 39 | end 40 | else -- entity to south 41 | if edir == 0 then 42 | direction = 0 43 | type = "input" 44 | else 45 | direction = 4 46 | type = "output" 47 | end 48 | end 49 | elseif util.is_ew(ldir) and ly >= ey-0.6 and ly <= ey+0.6 then 50 | -- loader and entity are aligned horizontally 51 | if lx > ex then -- entity to west 52 | if edir == 2 then 53 | direction = 2 54 | type = "input" 55 | else 56 | direction = 6 57 | type = "output" 58 | end 59 | else -- entity to east 60 | if edir == 6 then 61 | direction = 6 62 | type = "input" 63 | else 64 | direction = 2 65 | type = "output" 66 | end 67 | end 68 | end 69 | 70 | if not type then 71 | -- loader and entity are not aligned 72 | return false 73 | end 74 | 75 | if direction ~= ldir or loader.type == "entity-ghost" or loader.loader_type ~= type then 76 | util.update_miniloader(loader, direction, type) 77 | end 78 | return true 79 | end 80 | 81 | -- returns distance between p1 and p2 projected along half-axis identified by dir 82 | local function axis_distance(p1, p2, dir) 83 | if dir == 0 then 84 | return p1.y - p2.y 85 | elseif dir == 2 then 86 | return p2.x - p1.x 87 | elseif dir == 4 then 88 | return p2.y - p1.y 89 | elseif dir == 6 then 90 | return p1.x - p2.x 91 | end 92 | end 93 | 94 | -- Idiot snapping, face away from non belt entity 95 | local function idiot_snap(loader, entity) 96 | local lp = loader.position 97 | local ep = entity.position 98 | local direction = loader.direction 99 | local distance = axis_distance(ep, lp, direction) 100 | if axis_distance(ep, lp, util.opposite_direction(direction)) > distance then 101 | direction = util.opposite_direction(direction) 102 | end 103 | if loader.direction ~= direction or loader.type == "entity-ghost" or loader.loader_type ~= "output" then 104 | util.update_miniloader(loader, direction, "output") 105 | return true 106 | end 107 | return false 108 | end 109 | 110 | -- returns loaders next to a given entity 111 | local function find_loader_by_entity(entity) 112 | local position = entity.position 113 | local box = entity.prototype.selection_box 114 | local area = { 115 | {position.x + box.left_top.x - 1, position.y + box.left_top.y - 1}, 116 | {position.x + box.right_bottom.x + 1, position.y + box.right_bottom.y + 1} 117 | } 118 | local loaders = util.find_miniloaders{ 119 | surface = entity.surface, 120 | area=area, 121 | force=entity.force, 122 | } 123 | local out = {} 124 | for _, loader in ipairs(loaders) do 125 | local lpos = loader.position 126 | if lpos.x ~= position.x or lpos.y ~= position.y then 127 | out[#out+1] = loader 128 | end 129 | end 130 | return out 131 | end 132 | 133 | -- returns the miniloader connected to the belt of `entity`, if it exists 134 | local function find_loader_by_underground_belt(ug_belt) 135 | local ug_dir = util.belt_side(ug_belt) 136 | local loader = util.find_miniloaders{ 137 | surface = ug_belt.surface, 138 | position = util.moveposition(ug_belt.position, util.offset(ug_dir, 1, 0)), 139 | }[1] 140 | if loader and util.hood_side(loader) == ug_dir then 141 | return loader 142 | end 143 | return nil 144 | end 145 | 146 | local function is_snapping_target(entity) 147 | local prototype = entity.type == "entity-ghost" and entity.ghost_prototype or entity.prototype 148 | return prototype.has_flag("player-creation") and not prototype.has_flag("placeable-off-grid") 149 | end 150 | 151 | -- returns entities in front and behind a given loader 152 | local function find_entity_by_loader(loader) 153 | local positions = { 154 | util.moveposition(loader.position, util.offset(loader.direction, 1, 0)), 155 | util.moveposition(loader.position, util.offset(loader.direction, -1, 0)), 156 | } 157 | 158 | local out = {} 159 | for i = 1, #positions do 160 | local neighbors = loader.surface.find_entities_filtered{ 161 | position=positions[i], 162 | force=loader.force, 163 | } 164 | for _, ent in ipairs(neighbors) do 165 | if is_snapping_target(ent) then 166 | out[#out+1] = ent 167 | end 168 | end 169 | end 170 | return out 171 | end 172 | 173 | -- called when entity was rotated or non loader was built 174 | function snapping.check_for_loaders(event) 175 | local entity = event.created_entity or event.entity 176 | if not is_belt(entity) then 177 | return 178 | end 179 | 180 | local loaders = find_loader_by_entity(entity) 181 | for _, loader in ipairs(loaders) do 182 | snap_loader_to_target(loader, entity) 183 | end 184 | 185 | -- also scan other exit of underground belt 186 | if entity.type == "underground-belt" then 187 | local partner = entity.neighbours 188 | if partner then 189 | local loader = find_loader_by_underground_belt(partner) 190 | if loader then 191 | snap_loader_to_target(loader, partner) 192 | end 193 | end 194 | end 195 | end 196 | 197 | -- called when loader was built 198 | function snapping.snap_loader(loader) 199 | local entities = find_entity_by_loader(loader) 200 | for _, ent in ipairs(entities) do 201 | if is_belt(ent) and snap_loader_to_target(loader, ent) then 202 | return 203 | end 204 | end 205 | for _, ent in ipairs(entities) do 206 | if not is_belt(ent) and idiot_snap(loader, ent) then 207 | return 208 | end 209 | end 210 | end 211 | 212 | return snapping 213 | -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mspielberg/factorio-miniloader/2a0096672a2832d2e36bed0b0349155bb42697c3/thumbnail.png -------------------------------------------------------------------------------- /version.lua: -------------------------------------------------------------------------------- 1 | local version = {} 2 | 3 | function version.parse(str) 4 | local major, minor, patch = string.match(str, "^(%d+)%.(%d+)%.(.+)$") 5 | return {tonumber(major), tonumber(minor), tonumber(patch)} 6 | end 7 | 8 | function version.eq(v1, v2) 9 | for i = 1, 3 do 10 | if v1[i] ~= v2[i] then 11 | return false 12 | end 13 | end 14 | return true 15 | end 16 | 17 | function version.lt(v1, v2) 18 | for i = 1, 3 do 19 | if v1[i] < v2[i] then 20 | return true 21 | elseif v1[i] > v2[i] then 22 | return false 23 | end 24 | end 25 | return false 26 | end 27 | 28 | function version.gteq(v1, v2) 29 | return not version.lt(v1, v2) 30 | end 31 | 32 | function version.between(x, l, h) 33 | return version.gteq(x, l) and version.lt(x, h) 34 | end 35 | 36 | return version --------------------------------------------------------------------------------