├── LICENSE ├── README.md ├── changelog.txt ├── control.lua ├── data-final-fixes.lua ├── data-updates.lua ├── data.lua ├── description.md ├── graphics ├── entities │ └── high │ │ ├── beltbox-base.png │ │ ├── beltbox-mask.png │ │ ├── beltbox-shadow.png │ │ ├── beltbox-working.png │ │ ├── loader-back.png │ │ ├── loader-base.png │ │ ├── loader-mask.png │ │ └── loader-shadow.png └── icons │ ├── mipmaps │ ├── beltbox-icon-base.png │ ├── beltbox-icon-mask.png │ ├── loader-icon-base.png │ ├── loader-icon-mask.png │ ├── stacking-arrow-d.png │ └── stacking-arrow-u.png │ └── square │ ├── arrow-d-128.png │ ├── arrow-d-32.png │ ├── arrow-d-64.png │ ├── arrow-u-128.png │ ├── arrow-u-32.png │ ├── arrow-u-64.png │ ├── beltbox-icon-base-128.png │ ├── beltbox-icon-base-32.png │ ├── beltbox-icon-base-64.png │ ├── beltbox-icon-mask-128.png │ ├── beltbox-icon-mask-32.png │ ├── beltbox-icon-mask-64.png │ ├── blank.png │ ├── loader-icon-base-128.png │ ├── loader-icon-base-32.png │ ├── loader-icon-base-64.png │ ├── loader-icon-mask-128.png │ ├── loader-icon-mask-32.png │ ├── loader-icon-mask-64.png │ ├── stacked-advanced-circuit.png │ ├── stacked-battery.png │ ├── stacked-coal.png │ ├── stacked-copper-cable.png │ ├── stacked-copper-ore.png │ ├── stacked-copper-plate.png │ ├── stacked-electronic-circuit.png │ ├── stacked-iron-gear-wheel.png │ ├── stacked-iron-ore.png │ ├── stacked-iron-plate.png │ ├── stacked-iron-stick.png │ ├── stacked-plastic-bar.png │ ├── stacked-processing-unit.png │ ├── stacked-solid-fuel.png │ ├── stacked-steel-plate.png │ ├── stacked-stone-brick.png │ ├── stacked-stone.png │ ├── stacked-sulfur.png │ ├── stacked-tungsten-ore.png │ ├── stacked-uranium-235.png │ ├── stacked-uranium-238.png │ ├── stacked-uranium-ore.png │ └── stacked-wood.png ├── info.json ├── locale ├── en │ └── deadlock-beltboxes-loaders.cfg ├── fr │ └── fr.cfg ├── it │ └── deadlock-beltboxes-loaders.cfg ├── ja │ └── deadlock-beltboxes-loaders.cfg └── ru │ └── deadlock-beltboxes-loaders.cfg ├── migrations ├── deadlock-beltboxes-loaders_2.0.2.json ├── deadlock-beltboxes-loaders_2.0.2.lua └── logistics-recipes.lua ├── prototypes ├── create_beltbox.lua ├── create_loader.lua ├── create_stack.lua ├── public.lua ├── shared.lua ├── vanilla_stacks.lua └── vanilla_tiers.lua ├── settings.lua ├── sounds └── fan.ogg └── thumbnail.png /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2018 Deadlock989, Shane Madden 2 | 3 | This program is free software: you can redistribute it and/or modify it 4 | under the terms of the GNU General Public License as published by the 5 | Free Software Foundation, either version 3 of the License, or (at your 6 | option) any later version. 7 | 8 | This program is distributed in the hope that it will be useful, but 9 | WITHOUT ANY WARRANTY; without even the implied warranty of 10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 11 | Public License for more details. 12 | 13 | https://opensource.org/licenses/gpl-3.0 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Deadlock’s Stacking Beltboxes & Compact Loaders 2 | ========================== 3 | 4 | **DSB** is a Factorio mod which adds small 1x1 loaders and beltboxes. These can be used to stack items from a belt, in-line, 5 | greatly increasing belt throughput. 6 | 7 | If you are a Factorio modder, you can get DSB to automatically 8 | generate stacked versions of items from your own mods. A description of the DSB API is below. 9 | 10 | Step 1 11 | ------ 12 | 13 | Add “?deadlock-beltboxes-loaders” as an optional dependency in your mod’s **info.json**. 14 | For example: 15 | 16 | ~~~~ 17 | { 18 | "name": "DeadlockTweaks", 19 | "version": "0.1.0", 20 | "title": "Deadlock's Tweaks", 21 | "author": "Deadlock989", 22 | "contact": "", 23 | "homepage": "", 24 | "dependencies": ["base \>= 0.17.0", "?deadlock-beltboxes-loaders], 25 | "description": "Some small quality of life adjustments.", 26 | "factorio_version": "0.17" 27 | } 28 | ~~~~ 29 | 30 | Step 2 31 | ------ 32 | 33 | DSB exposes a set of functions which handle stack creation (and optionally 34 | beltbox and loader tier creation) for you. You should call these functions from your mod’s 35 | **data-final-fixes.lua**. Check that **deadlock** exists before you try 36 | and call any of the functions, so that your mod will still run without errors if 37 | DSB isn’t installed. For example: 38 | 39 | ~~~~ 40 | -- [data-final-fixes.lua] 41 | -- this mod makes diamonds. don’t dig straight down 42 | -- we already created our items earlier on 43 | 44 | -- get DSB to stack my itamz 45 | if deadlock then 46 | -- repeat this for every item you want crated 47 | deadlock.add_stack("deadlock-uber-diamond", "__DeadlockTweaks__/graphics/icons/stacked-diamond.png", "deadlock-stacking-1", 64) 48 | end 49 | ~~~~ 50 | 51 | Alternatively, if you have a long list of items which you want to insert into 52 | different technologies, you could put them into some kind of array or table and 53 | then loop through them. 54 | 55 | This is the simplest use case. Several more functions are provided: these are 56 | described on the following pages. 57 | 58 | deadlock.add_stack() 59 | ---------------------------- 60 | 61 | This is the function used to crate things that DSB doesn’t handle by default. It 62 | can take up to six parameters. A full call looks like this: 63 | **deadlock.add_stack(item_name, graphic_path, target_tech, icon_size, item_type, mipmap_levels)** 64 | 65 | | **Parameter** | **Optional / Mandatory?** | **Explanation** | 66 | |------------------|---------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 67 | | **item_name** | Mandatory | String. The name of the item you want crated, e.g. “iron-plate”. | 68 | | **graphic_path** | Optional | String. The path to an icon for your stacked item. Can be omitted, but this is bad for performance (see "More Details" below). | 69 | | **target_tech** | Optional | String. The technology name (e.g. “deadlock-stacking-1”) that the crating recipe unlocks will be inserted into. If specified, the technology **must already exist** as a prototype in data.raw. If omitted or nil, the mod won’t update any technologies, and you’ll have to handle gaining access to the recipes yourself. | 70 | | **icon_size** | Optional | Integer. The size of your custom icon in pixels. Defaults to 64. Not used if no icon is supplied. | 71 | | **item_type** | Optional | String. The type of item, e.g. "item", "ammo", "repair-tool" etc. Defaults to "item". | 72 | | **mipmap_levels**| Optional | Integer. The mipmap levels of your custom icon. Defaults to nil. Not used if no icon is supplied. | 73 | 74 | You can omit an optional parameter or specify nil to use the defaults. 75 | 76 | Note that if you specify an item which has already been stacked, you may get unwanted results. 77 | Consider using destroy_stack(), described below, to remove the item before you overwrite 78 | it. 79 | 80 | deadlock.destroy_stack() 81 | -------------------------------- 82 | 83 | This takes one parameter, the item name: 84 | **deadlock.destroy_stack(item_name)** 85 | 86 | Calling this function will destroy the stacked version of the item, **all** 87 | recipes which include the stack as an ingredient or result 88 | (i.e. the stacking and unstacking recipes at minimum, but could in theory include 89 | any other modded recipe that has used a stack as an ingredient), and removes 90 | **all** references to the deleted recipes from **all** technologies. 91 | 92 | Bear in mind that there could be other mods which expect any given stack to 93 | exist. If you destroy them and don’t re-create them, you’re responsible for 94 | sorting out any issues that causes. You can also use this function to clear a 95 | stacked item and then rebuild it with add_stack(), for example to resolve 96 | conflicts between two overhaul mods. 97 | 98 | deadlock.destroy_vanilla_stacks() 99 | ----------------------------------------- 100 | 101 | This takes no parameters and removes all of the vanilla stacked items and recipes 102 | that DSB creates by default. Effectively it calls destroy_stack() on every item 103 | the mod sets up in the early data stage. Use this if you want to wipe the slate 104 | clean and rebuild from scratch. 105 | 106 | deadlock.add_tier() 107 | --------------------------- 108 | 109 | By default, DSB creates three tiers of beltboxes and loaders, which correspond 110 | to yellow, red and blue belts in vanilla; it also creates three tiers of 111 | technology which each unlock the machines and a collection of stacking recipes. You 112 | can use this function to create new tiers of machine unlocked by new 113 | technologies which correspond to belts that are provided by other mods (or have 114 | some other reason for existing). Or you can use it to replace the default tiers 115 | with different settings. 116 | 117 | The function takes a table as its single parameter. The table can have the 118 | following key/value pairs: 119 | 120 | | **Parameter** | **Optional / Mandatory?** | **Explanation** | 121 | |---------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 122 | | **transport_belt** | Mandatory | String. The prefix of the corresponding transport belt, e.g. "uber-". Used to calculate speeds. | 123 | | **underground_belt**| Optional if beltbox_ingredients and loader_ingredients are specified | String. The name of the corresponding underground belt. By default, DSB bases beltbox and loader recipes on underground recipes. You can omit this parameter but you must then specify your own ingredients. | 124 | | **splitter** | Optional | String. Currently unused in this mod, but passed to styling mods if present. | 125 | | **colour** | Optional | Colour table. The tint colour for the machines. Defaults to pink. | 126 | | **technology** | Recommended | String. The name of the corresponding logistics technology. Used to unlock loaders. Stacking recipes will not be unlocked if this is not defined. | 127 | | **order** | Recommended | String. Order string for beltboxes and loaders. | 128 | | **beltbox** | Optional | String. Name of the beltbox prototype that will be created. Defaults to transport_belt.."-beltbox". | 129 | | **beltbox_technology**| Optional | String. Name of the technology that unlocks the beltboxes and stacked items in the same tier. Defaults to beltbox_name but can be overridden - vanilla tiers use "deadlock-stacking-[1-3]" for legacy compatability. | 130 | | **beltbox_ingredients**| Optional if underground_belt is specified | Table of IngredientPrototypes. The ingredients for the beltbox's recipe. Defaults to a formula based on underground_belt. | 131 | | **beltbox_recipe** | Optional | String. Can be used to override the beltbox recipe prototype name. | 132 | | **beltbox_item** | Optional | String. Can be used to override the beltbox item prototype name. | 133 | | **beltbox_category** | Optional | String. The crafting category for the beltbox. Defaults to "crafting". Use "crafting-with-fluid" if there is fluid in the recipe. | 134 | | **loader** | Optional | String. Name of the loader prototype that will be created. Defaults to transport_belt.."-loader". | 135 | | **loader_ingredients**| Optional if underground_belt is specified | Table of IngredientPrototypes. The ingredients for the loader's recipe. Defaults to a formula based on underground_belt. | 136 | | **loader_recipe** | Optional | String. Can be used to override the loader recipe prototype name. | 137 | | **loader_item** | Optional | String. Can be used to override the loader item prototype name. | 138 | | **loader_category** | Optional | String. The crafting category for the loader. Defaults to "crafting". Use "crafting-with-fluid" if there is fluid in the recipe. | 139 | 140 | Here is an example from the Integrations mod which adds support for a tier 4 beltbox and loader: 141 | 142 | ~~~~ 143 | deadlock.add_tier({ 144 | transport_belt = "rapid-transport-belt-mk1", 145 | colour = {r=10, g=225, b=25}, 146 | underground_belt = "rapid-transport-belt-to-ground-mk1", 147 | splitter = "rapid-splitter-mk1", 148 | technology = "logistics-4", 149 | order = "d", 150 | loader_ingredients = { 151 | {"express-transport-belt-loader",1}, 152 | {"iron-gear-wheel",20}, 153 | {amount = 40,name = "lubricant",type = "fluid"}, 154 | }, 155 | loader_category = "crafting-with-fluid", 156 | beltbox_ingredients = { 157 | {"express-transport-belt-beltbox",1}, 158 | {"iron-plate",40}, 159 | {"iron-gear-wheel",40}, 160 | {"processing-unit",5}, 161 | }, 162 | beltbox_technology = "deadlock-stacking-4", 163 | }) 164 | ~~~~ 165 | 166 | More details 167 | ------------ 168 | 169 | **Data stages.** When should you call these functions? In 170 | **data-final-fixes.lua**. Some functions may work before that in some 171 | situations, but no guarantees. There is something of an arms race going on 172 | between mods using data.lua, data-updates.lua and data-final-fixes.lua to do 173 | different things with vanilla recipes, their own, and to make changes to other 174 | mods. The general tendency is for things to happen later and later as mods try 175 | to catch and/or prevent each other’s changes. There isn’t really much we can do 176 | about that. 177 | 178 | **Automatic icons.** When using add_stack(), if you specify the icon path and icon size as nil, 179 | then DSB will create a triple-layered icon from the base item's icon automatically. There are two 180 | issues with doing this: it won't necessarily look very good, and it is bad for rendering 181 | performance. Remember that thousands of these items can be on the screen at once. Rendering 182 | performance will be taxed by a minimum of 4x the rendering effort if you used stacked icons, more 183 | if the base item itself already has layers. Try and supply your own stacked item icons wherever possible, 184 | or people trying to use your mod on a low-spec GPU may suffer for it. The feature is only 185 | included for legacy mod support: the standard game log will be spammed with warnings when 186 | layered icons are created. 187 | 188 | **Tech/migration.** If you add stacks to DSB technologies and then change them later, or 189 | remove anything that they provide, **you are responsible for your own 190 | migrations**. See DSB’s migrations folders for an example. 191 | 192 | **Errors.** In some cases, you can call the API functions to create an item or a 193 | tier with parameters which would not allow the game to load at all. In those 194 | cases, the loading process will halt with an error message. **Please read it.** 195 | In other cases, you can specify things that would allow the game to load but 196 | just don’t make much sense. In those cases, the game will continue to load but 197 | the function call may be skipped and an error or warning will be printed in the 198 | default game log. So if your stacked items or beltboxes are missing, check the log. 199 | 200 | **“Helper” or “bridge” mods.** If your favourite modder doesn’t want to / have 201 | time to provide support for stacking/crating, you could make your own mini 202 | “helper” mod which simply bridges the gap. In this case you would require both 203 | their mod and DSB as compulsory dependencies, not optional, and then all 204 | your mini-mod does is loop through some items and maybe create a new tier if the 205 | target mod provides different belts. 206 | 207 | If you run into problems and have tried to solve them yourself but are stuck, 208 | use the [Factorio forums 209 | thread](https://forums.factorio.com/viewtopic.php?f=94&t=57264) to contact us. 210 | Provide any error messages and show your code – we can’t guess from a vague 211 | description. 212 | 213 | This mod was originally authored by Deadlock989. It was ported to 0.17 and is 214 | now maintained by shanemadden with contributions from Deadlock989. 215 | -------------------------------------------------------------------------------- /changelog.txt: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------------------------- 2 | Version: 2.6.0 3 | Date: 06. 01. 2025 4 | Changes: 5 | - Corrected the recipe for T4 loaders/beltboxes to use T3 instead of T2 6 | - Allow T3/T4 loaders/beltboxes to be made in foundaries when Space Age is present, matching the belts of that tier 7 | --------------------------------------------------------------------------------------------------- 8 | Version: 2.5.0 9 | Date: 23. 10. 2024 10 | Changes: 11 | - Updated for Factorio 2.0 12 | - Added compatibility with Space Age, a 4th tier of loaders/beltboxes will be added if Space Age is active 13 | - Turbo loaders/beltboxes are currently only localized in English, PRs with translations are welcome! 14 | - Removed the 'low' graphics as `hr_version` as the low/high split has been removed from the game 15 | --------------------------------------------------------------------------------------------------- 16 | Version: 2.4.2 17 | Date: 09. 05. 2021 18 | Changes: 19 | - Remove old compatibility workarounds from build event code, and add an event filter to improve performance. 20 | --------------------------------------------------------------------------------------------------- 21 | Version: 2.4.1 22 | Date: 13. 01. 2021 23 | Changes: 24 | - Remove check for whether loaders are from this mod for snapping to improve compatibility with other mods. Reminder: snapping options can be disabled in settings if desired. 25 | --------------------------------------------------------------------------------------------------- 26 | Version: 2.4.0 27 | Date: 24. 11. 2020 28 | Changes: 29 | - Updated for Factorio 1.1.0, courtesy of billbo99 30 | --------------------------------------------------------------------------------------------------- 31 | Version: 2.3.7 32 | Date: 31. 10. 2020 33 | Bugfixes: 34 | - Fix multiplication of fuel value for items with non-whole-number values, courtesy of billbo99 35 | --------------------------------------------------------------------------------------------------- 36 | Version: 2.3.6 37 | Date: 26. 07. 2020 38 | Bugfixes: 39 | - Use icons property instead of icon when both are present and fix bad size assumption, courtesy of kirazy on GitHub 40 | --------------------------------------------------------------------------------------------------- 41 | Version: 2.3.5 42 | Date: 11. 04. 2020 43 | Bugfixes: 44 | - Fix potential desync due to unneeded global variables 45 | --------------------------------------------------------------------------------------------------- 46 | Version: 2.3.4 47 | Date: 22. 03. 2020 48 | Changes: 49 | - Thanks to shelaf for adding a Japanese translation 50 | --------------------------------------------------------------------------------------------------- 51 | Version: 2.3.3 52 | Date: 07. 03. 2020 53 | Bugfixes: 54 | - Fix upgrade planner properties for new entity type 55 | --------------------------------------------------------------------------------------------------- 56 | Version: 2.3.2 57 | Date: 01. 03. 2020 58 | Changes: 59 | - Allow stacking of rail items, thanks to billbo99 60 | --------------------------------------------------------------------------------------------------- 61 | Version: 2.3.1 62 | Date: 17. 02. 2020 63 | Bugfixes: 64 | - Fix a crash when a base item for a stacked item is deleted 65 | --------------------------------------------------------------------------------------------------- 66 | Version: 2.3.0 67 | Date: 25. 01. 2020 68 | Changes: 69 | - Support 0.18 thanks to billbo99 70 | - Loaders changed to use type = "loader-1x1" 71 | --------------------------------------------------------------------------------------------------- 72 | Version: 2.2.3 73 | Date: 14. 12. 2019 74 | Changes: 75 | - Use an item's localised_name for stacked item name generation to match the underlying item if the locale file has been overridden for it 76 | --------------------------------------------------------------------------------------------------- 77 | Version: 2.2.2 78 | Date: 28. 09. 2019 79 | Changes: 80 | - Attempt to prevent an failure to load when a deleted item is checked for stacking density 81 | --------------------------------------------------------------------------------------------------- 82 | Version: 2.2.1 83 | Date: 25. 08. 2019 84 | Changes: 85 | - Improves loader snapping for adjacent loaders and inventory snapping belt hints - thanks to meonester on GitHub 86 | - When auto-unstacking is enabled, automatically unstack items gained via mining an entity - thanks to Doublespin on GitHub 87 | - Add stack density options for more powers of 2 instead of 10; reminder to understand the maximum stack size implications of these settings; a stack size of 128 will drastically cut the amount of items that can be stored in a train or chest for items that stack to 200. 88 | --------------------------------------------------------------------------------------------------- 89 | Version: 2.2.0 90 | Date: 08. 06. 2019 91 | Changes: 92 | - Thanks to Linver for adding an Italian translation. 93 | API: 94 | - NEW: deadlock.destroy_stack(). This deletes the stacked version of an item, all recipes which use it, and all tech unlocks for those recipes. 95 | - NEW: deadlock.destroy_vanilla_stacks(). This deletes all the vanilla stacked items and all references to them. 96 | - deadlock.add_stack() now has an optional extra parameter for specifying mipmap level - this is only ever used if you supply your own icon for the stack. 97 | - Added warnings in the standard log when deprecated legacy functions are used and a hint to use an alternative. 98 | - Moved vanilla items-per-tier lists into shared data. 99 | - Moved item/recipe order meta-tables into shared data. 100 | - Moved player hand unstacking call out of shared data and into data-final-fixes (to prevent repetitions). 101 | --------------------------------------------------------------------------------------------------- 102 | Version: 2.1.13 103 | Date: 02. 06. 2019 104 | Changes: 105 | - Added Russian translation courtesy of JohnTheCoolingFan on GitHub 106 | --------------------------------------------------------------------------------------------------- 107 | Version: 2.1.12 108 | Date: 13. 05. 2019 109 | Changes: 110 | - Normalize beltbox and stack recipe speeds to 1/2/3 at vanilla speeds 111 | --------------------------------------------------------------------------------------------------- 112 | Version: 2.1.11 113 | Date: 02. 05. 2019 114 | Changes: 115 | - Update for character name changes in 0.17.35 116 | --------------------------------------------------------------------------------------------------- 117 | Version: 2.1.10 118 | Date: 13. 04. 2019 119 | Changes: 120 | - Change to using new emissions_per_minute parameter for pollution values 121 | --------------------------------------------------------------------------------------------------- 122 | Version: 2.1.9 123 | Date: 12. 04. 2019 124 | Changes: 125 | - Improved tint mask graphics 126 | --------------------------------------------------------------------------------------------------- 127 | Version: 2.1.8 128 | Date: 10. 04. 2019 129 | Bugfixes: 130 | - Updated beltbox render order to fix occasional flickering issues 131 | --------------------------------------------------------------------------------------------------- 132 | Version: 2.1.7 133 | Date: 06. 04. 2019 134 | Changes: 135 | - Re-added optional dependency on ReStack 136 | - Added new data stage helper function to the API to get the effective stack size for each item without having to dig into recipes, since it can now vary based on settings and the items themselves 137 | --------------------------------------------------------------------------------------------------- 138 | Version: 2.1.6 139 | Date: 01. 04. 2019 140 | Changes: 141 | - Added a startup option to set a stack size other than 5 142 | - Attempted to fix potential situations where recipes added by third party mods weren't unlocked for existing saves 143 | --------------------------------------------------------------------------------------------------- 144 | Version: 2.1.5 145 | Date: 31. 03. 2019 146 | Changes: 147 | - Update some stacked item attributes late in the loading process to account for other mods' changes 148 | - Removed optional dependency on bobplates that's no longer needed 149 | --------------------------------------------------------------------------------------------------- 150 | Version: 2.1.4 151 | Date: 30. 03. 2019 152 | Bugfixes: 153 | - Fix recipe icon generation for items with 128 pixel icons 154 | --------------------------------------------------------------------------------------------------- 155 | Version: 2.1.3 156 | Date: 25. 03. 2019 157 | Changes: 158 | - Added French translation courtesy of Krysh Nar on GitHub 159 | --------------------------------------------------------------------------------------------------- 160 | Version: 2.1.2 161 | Date: 24. 03. 2019 162 | Changes: 163 | - Update masks with corrected texture 164 | --------------------------------------------------------------------------------------------------- 165 | Version: 2.1.1 166 | Date: 24. 03. 2019 167 | Changes: 168 | - Drop pollution on beltboxes to bring it in line with the intended pollution amount. 169 | - Re-add fast-replaceable-no-build-while-moving flag to loaders. 170 | --------------------------------------------------------------------------------------------------- 171 | Version: 2.1.0 172 | Date: 23. 03. 2019 173 | Changes: 174 | - Brand new graphics for beltboxes and loaders which match the 0.17 belt style better. 175 | - There is a new mod setting to turn off the alt-mode recipe icon shown on beltboxes. 176 | --------------------------------------------------------------------------------------------------- 177 | Version: 2.0.10 178 | Date: 19. 03. 2019 179 | Changes: 180 | - Add optional dep of bobplates because of the numerous changes it makes to vanilla items 181 | - Alter localized name of the tier 1 beltbox to make more sense alongside a tier named "Basic" 182 | --------------------------------------------------------------------------------------------------- 183 | Version: 2.0.9 184 | Date: 14. 03. 2019 185 | Changes: 186 | - Update beltbox emission attributes for new format in Factorio 0.17.12 (requires this version) 187 | - Split loaders and beltboxes into their own subgroups 188 | - Add options to split loaders and beltboxes into strict fast replace groups 189 | --------------------------------------------------------------------------------------------------- 190 | Version: 2.0.8 191 | Date: 10. 03. 2019 192 | Changes: 193 | - Alter the way the entity tables are created for loaders to be safe if the vanilla loaders have been changed - fixes conflict with Loader Redux 194 | - Move loaders to the transport-belt fast replace group, matching beltboxes 195 | --------------------------------------------------------------------------------------------------- 196 | Version: 2.0.7 197 | Date: 06. 03. 2019 198 | Changes: 199 | - Add a mechanism to the snapping logic to only work on loaders added by this mod 200 | --------------------------------------------------------------------------------------------------- 201 | Version: 2.0.6 202 | Date: 05. 03. 2019 203 | Changes: 204 | - Set the auto-unstack option back to disabled by default, those who prefer it can enable in settings 205 | - Add upgrade relationships between loaders and beltboxes for the base upgrade planner tool 206 | --------------------------------------------------------------------------------------------------- 207 | Version: 2.0.5 208 | Date: 04. 03. 2019 209 | Bugfixes: 210 | - Fix error in tech dependencies when beltboxes are disabled 211 | --------------------------------------------------------------------------------------------------- 212 | Version: 2.0.4 213 | Date: 03. 03. 2019 214 | Changes: 215 | - Set each stacking tech to require the prior level 216 | --------------------------------------------------------------------------------------------------- 217 | Version: 2.0.3 218 | Date: 03. 03. 2019 219 | Bugfixes: 220 | - Allow for belts with old-style belt end animations in addition to the new belt_animation_set, fixing compatibility with FactorioExtended-Plus 221 | --------------------------------------------------------------------------------------------------- 222 | Version: 2.0.2 223 | Date: 02. 03. 2019 224 | Bugfixes: 225 | - Fix stacking of formerly raw wood 226 | --------------------------------------------------------------------------------------------------- 227 | Version: 2.0.1 228 | Date: 02. 03. 2019 229 | Changes: 230 | - Fix info.json version number causing odd display in mod portal 231 | --------------------------------------------------------------------------------------------------- 232 | Version: 2.0.0 233 | Date: 02. 03. 2019 234 | Changes: 235 | - Initial release - combines functionality of DeadlockLoaders and DeadlockStacking (if you don't want one or the other, disable them in options) 236 | - If you have an existing save, you also need the updated versions of the old mods for the first load - please see the mod portal for instructions if you have issues 237 | -------------------------------------------------------------------------------- /control.lua: -------------------------------------------------------------------------------- 1 | local STACK_SIZE = settings.startup["deadlock-stack-size"].value 2 | 3 | -- work with directions 4 | local opposite = { 5 | [defines.direction.north] = defines.direction.south, 6 | [defines.direction.south] = defines.direction.north, 7 | [defines.direction.east] = defines.direction.west, 8 | [defines.direction.west] = defines.direction.east, 9 | } 10 | local dir2vector = { 11 | [defines.direction.north] = {x=0, y=-1}, 12 | [defines.direction.south] = {x=0, y=1}, 13 | [defines.direction.east] = {x=1, y=0}, 14 | [defines.direction.west] = {x=-1, y=0}, 15 | } 16 | 17 | -- add vectors 18 | local function add_vectors(v1, v2) 19 | return {v1.x + v2.x, v1.y + v2.y} 20 | end 21 | 22 | -- return all entities 1 tile away in specified direction 23 | local function get_neighbour_entities(entity, direction) 24 | return entity.surface.find_entities_filtered{ position = add_vectors(entity.position, dir2vector[direction]) } 25 | end 26 | 27 | -- does any entity in list have an inventory we can work with 28 | local function are_loadable(entities) 29 | for _,entity in pairs(entities) do 30 | if entity.get_inventory(defines.inventory.chest) or 31 | entity.get_inventory(defines.inventory.furnace_source) or 32 | entity.get_inventory(defines.inventory.assembling_machine_input) or 33 | entity.get_inventory(defines.inventory.lab_input) or 34 | entity.get_inventory(defines.inventory.rocket_silo_rocket) 35 | then return true end 36 | end 37 | return false 38 | end 39 | 40 | -- belt facing detection 41 | local function are_belt_facing(entities, direction) 42 | for _,entity in pairs(entities) do 43 | if (entity.type == "transport-belt" or 44 | entity.type == "underground-belt" or 45 | entity.type == "splitter" or 46 | entity.type == "loader-1x1") and 47 | entity.direction == direction 48 | then return true end 49 | end 50 | return false 51 | end 52 | 53 | -- if there's a belt behind, mode follows the direction of the belt 54 | -- else if there's a belt ahead, stop 55 | -- else if there's an inventory behind but not ahead, turn around 56 | -- else if there's an inventory ahead but not behind, turn around and switch mode 57 | -- else if no inventories and a belt ahead, turn around; also switch mode if belt is facing towards 58 | local function on_built_entity(event) 59 | local built = event.entity 60 | -- invalid build? don't bother with faked "revived" property from pre-1.0 Nanobots/Bluebuild, those shenanigans can only be passed in script_raised_* events now 61 | -- also no need to check entity type since we can filter for it on the event handler 62 | if not built or not built.valid then return end 63 | local snap2inv = settings.get_player_settings(game.players[event.player_index])["deadlock-loaders-snap-to-inventories"].value 64 | local snap2belt = settings.get_player_settings(game.players[event.player_index])["deadlock-loaders-snap-to-belts"].value 65 | -- no need to check anything if configs are off 66 | if not snap2inv and not snap2belt then 67 | return 68 | end 69 | -- get the entities from both ends 70 | local belt_end = get_neighbour_entities(built, built.direction) 71 | local loading_end = get_neighbour_entities(built, opposite[built.direction]) 72 | 73 | if snap2belt and are_belt_facing(belt_end, opposite[built.direction]) then 74 | -- there's a belt facing toward the belt-side of the loader, so we want to be in input mode 75 | built.rotate( {by_player = event.player_index} ) 76 | elseif snap2belt and are_belt_facing(belt_end, built.direction) then 77 | -- there's a belt facing away from the belt-side of the loader, so we want to be certain to stay in output mode, stop further checks 78 | return 79 | elseif snap2inv and are_loadable(loading_end) then 80 | -- there's a loadable entity on the loader end 81 | -- as long as there's no belt facing away from the belt end, flip into input mode to load it up 82 | if not are_belt_facing(belt_end, built.direction) then 83 | built.rotate( {by_player = event.player_index} ) 84 | end 85 | elseif are_loadable(belt_end) then 86 | -- there's a loadable entity on the belt end but not on the loader end, flip around and go into input mode to load it up 87 | built.direction = opposite[built.direction] 88 | -- unless there's a belt facing away, then stay in output mode 89 | if not are_belt_facing(loading_end, built.direction) then 90 | -- that wasn't the case so we're safe to go into input mode 91 | built.rotate( {by_player = event.player_index} ) 92 | end 93 | elseif snap2belt and are_belt_facing(loading_end, built.direction) then 94 | -- there's a belt facing into the loader end, switch into input mode and flip 95 | built.direction = opposite[built.direction] 96 | built.rotate( {by_player = event.player_index} ) 97 | elseif snap2belt and are_belt_facing(loading_end, opposite[built.direction]) then 98 | -- there's a belt facing away from the loader end, flip 99 | built.direction = opposite[built.direction] 100 | end 101 | end 102 | -- add filter to save another millisecond 103 | script.on_event(defines.events.on_built_entity, on_built_entity, {{filter="type", type = "loader-1x1"}}) 104 | 105 | -- auto-unstacking by ownlyme 106 | local function auto_unstack(item_name, item_count, sending_inventory, receiving_inventory) 107 | -- item_name: The name of the stacked item which should be unstacked 108 | -- item_count: The number of items that should be unstacked 109 | -- sending_inventory: the inventory that contains the stacked item 110 | -- receiving_inventory: the inventory that receives the unstacked items 111 | if string.sub(item_name, 1, 15) == "deadlock-stack-" then 112 | -- attempt to auto-unstack 113 | -- try to add a stack worth of the source item to the inventory 114 | local add_count = STACK_SIZE 115 | -- if the base item's stack size is lower than the configured STACK_SIZE then 116 | -- this should reward the lower of the two 117 | local prototype = prototypes.item[string.sub(item_name, 16)] 118 | if STACK_SIZE > prototype.stack_size then 119 | add_count = prototype.stack_size 120 | end 121 | local inserted = receiving_inventory.insert({ 122 | name = string.sub(item_name, 16), 123 | count = add_count * item_count, 124 | }) 125 | 126 | local partial_inserted = inserted % add_count 127 | -- if player inventory is nearly full it may happen that just 8 items are inserted with add_count==5 128 | -- partial inserted then will be 3 129 | if partial_inserted > 0 then 130 | receiving_inventory.remove({ 131 | name = string.sub(item_name, 16), 132 | count = partial_inserted, 133 | }) 134 | end 135 | -- now remove the inserted items in their stacked variant. With the example above this is 1 stacked item 136 | local full_stack_inserted = math.floor(inserted / add_count) 137 | if full_stack_inserted > 0 then 138 | sending_inventory.remove({ 139 | name = item_name, 140 | count = full_stack_inserted, 141 | }) 142 | end 143 | end 144 | end 145 | 146 | local inventories_to_check = { 147 | defines.inventory.chest, 148 | defines.inventory.furnace_source, 149 | defines.inventory.furnace_result, 150 | defines.inventory.cargo_wagon, 151 | defines.inventory.assembling_machine_input, 152 | defines.inventory.assembling_machine_output, 153 | defines.inventory.robot_cargo, 154 | } 155 | local function try_unstacking(entity, inventory_type, player_inventory) 156 | local mined_entity_inventory = entity.get_inventory(inventory_type) 157 | if mined_entity_inventory then 158 | for item_name, item_count in pairs(mined_entity_inventory.get_contents()) do 159 | auto_unstack(item_name, item_count, mined_entity_inventory, player_inventory) 160 | end 161 | end 162 | end 163 | 164 | local function on_pre_player_mined_item(event) 165 | local player_inventory = game.players[event.player_index].get_main_inventory() 166 | 167 | for i, v in ipairs(inventories_to_check) do 168 | try_unstacking(event.entity, v, player_inventory) 169 | end 170 | end 171 | local function on_picked_up_item(event) 172 | local player_inventory = game.players[event.player_index].get_main_inventory() 173 | auto_unstack(event.item_stack.name, event.item_stack.count, player_inventory, player_inventory) 174 | end 175 | local function on_player_mined_entity(event) 176 | local player_inventory = game.players[event.player_index].get_main_inventory() 177 | for item_name, item_count in pairs(event.buffer.get_contents()) do 178 | auto_unstack(item_name, item_count, event.buffer, player_inventory) 179 | end 180 | end 181 | -- conditionally register based on the state of the setting so it's not costing any performance when disabled 182 | local function on_load(event) 183 | if settings.startup["deadlock-stacking-auto-unstack"].value then 184 | script.on_event(defines.events.on_picked_up_item, on_picked_up_item) -- works on items that are picked up with f key 185 | script.on_event(defines.events.on_player_mined_item, on_picked_up_item) -- works on items which are directly mined from the ground 186 | script.on_event(defines.events.on_player_mined_entity, on_player_mined_entity) -- works on mined belts that carry items 187 | script.on_event(defines.events.on_pre_player_mined_item, on_pre_player_mined_item) -- works on mined entities with inventories that carry items 188 | end 189 | end 190 | script.on_load(on_load) 191 | script.on_init(on_load) 192 | 193 | local function on_configuration_changed(config) 194 | -- scan the forces' technologies for any of our loaders or beltboxes that should be 195 | -- unlocked but aren't, likely due to the mod adding them just being added to the save 196 | for _, force in pairs(game.forces) do 197 | for tech_name, tech_table in pairs(force.technologies) do 198 | if tech_table.researched then 199 | -- find any beltboxes or loaders or stacks in effects and unlock 200 | for _, effect_table in ipairs(tech_table.prototype.effects) do 201 | if effect_table.type == "unlock-recipe" and (string.find(prototypes.recipe[effect_table.recipe].order, "%-deadlock%-") or string.find(prototypes.recipe[effect_table.recipe].name, "deadlock%-")) then 202 | force.recipes[effect_table.recipe].enabled = true 203 | end 204 | end 205 | end 206 | end 207 | end 208 | end 209 | script.on_configuration_changed(on_configuration_changed) 210 | -------------------------------------------------------------------------------- /data-final-fixes.lua: -------------------------------------------------------------------------------- 1 | -- run late stack updates for changes to stack sizes, fuel values, etc 2 | deadlock.deferred_stacked_item_updates() 3 | 4 | -- update the character prototype to allow "hand-unstacking" 5 | table.insert(data.raw["character"]["character"].crafting_categories, "unstacking") 6 | -------------------------------------------------------------------------------- /data-updates.lua: -------------------------------------------------------------------------------- 1 | -- create vanilla stacks 2 | require("prototypes.vanilla_stacks") 3 | 4 | -- hit the subgroups again to cover any added since data.lua load 5 | for _, group in pairs(data.raw["item-group"]) do 6 | if not data.raw["item-subgroup"][string.format("stacks-%s", group.name)] then 7 | data:extend({ 8 | { 9 | type = "item-subgroup", 10 | name = string.format("stacks-%s", group.name), 11 | group = group.name, 12 | order = "zzzzz", 13 | }, 14 | }) 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /data.lua: -------------------------------------------------------------------------------- 1 | -- internal functions for prototype manipulation 2 | require("prototypes.create_beltbox") 3 | require("prototypes.create_loader") 4 | require("prototypes.create_stack") 5 | -- mod API 6 | require("prototypes.public") 7 | -- vanilla tiers 8 | require("prototypes.vanilla_tiers") 9 | -------------------------------------------------------------------------------- /description.md: -------------------------------------------------------------------------------- 1 | ![beltbox](https://i.imgur.com/JoFG35F.gif) 2 | 3 | # Deadlock's Stacking Beltboxes and Compact Loaders 4 | 5 | [Deadlock's Stacking Beltboxes](https://mods.factorio.com/mod/DeadlockStacking) and [Deadlock's Compact Loaders](https://mods.factorio.com/mod/DeadlockLoaders) are now combined into one mod. 6 | 7 | For existing saves, the updated versions of the existing Deadlock mod(s) you were using must be loaded to migrate your existing loaders and beltboxes to this new mod - see those mods' pages for more details on how to migrate those saves. 8 | 9 | The integration with Bob's Logistics, Factorio Extended (and Extended Plus), and Xander Mod has been moved to a separate mod - if you're using loaders or beltboxes with their belt tiers, also [get the integrations mod](https://mods.factorio.com/mod/deadlock-integrations). 10 | 11 | Note that the belt reskin and map recolor options are not yet implemented. 12 | 13 | Any issues with the new version? Let us know in the [forum thread.](https://forums.factorio.com/viewtopic.php?f=94&t=57264) 14 | 15 | # Credits 16 | 17 | * Concept, graphics, and originally authored by [Deadlock989](https://mods.factorio.com/user/deadlock989). 18 | * Maintained by [shanemadden](https://mods.factorio.com/user/shanemadden). 19 | 20 | # Inter-mod support 21 | 22 | The modding API available in the new version should be almost completely unchanged from the previous versions. An updated dedicated document is coming soon for the modding API, but here's what you need to know: 23 | 24 | - The default icon_size has changed to 64x64 for the API calls to add stacked items, since your icons are likely still 32x32 you'll need to pass an icon size. (Vanilla icons are still 32x32, per fff-277 we can expect the new ones sometime during 0.17 experimental) 25 | 26 | A call that looked like this: 27 | 28 | deadlock_stacking.create("raw-wood", icon_path, "deadlock-stacking-1") 29 | 30 | with a 32x32 icon will need to be changed to this for 0.17: 31 | 32 | deadlock_stacking.create("raw-wood", icon_path, "deadlock-stacking-1", 32) 33 | 34 | - A new API function is available to create loaders and beltboxes to match any tier of belt. Full documentation coming soon, but intrepid modders will find [parameter details in the comments](https://github.com/shanemadden/factorio-deadlock-beltboxes-loaders/blob/master/prototypes/public.lua#L5) and [examples in the base code](https://github.com/shanemadden/factorio-deadlock-beltboxes-loaders/blob/master/prototypes/vanilla_tiers.lua). 35 | -------------------------------------------------------------------------------- /graphics/entities/high/beltbox-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/beltbox-base.png -------------------------------------------------------------------------------- /graphics/entities/high/beltbox-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/beltbox-mask.png -------------------------------------------------------------------------------- /graphics/entities/high/beltbox-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/beltbox-shadow.png -------------------------------------------------------------------------------- /graphics/entities/high/beltbox-working.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/beltbox-working.png -------------------------------------------------------------------------------- /graphics/entities/high/loader-back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/loader-back.png -------------------------------------------------------------------------------- /graphics/entities/high/loader-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/loader-base.png -------------------------------------------------------------------------------- /graphics/entities/high/loader-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/loader-mask.png -------------------------------------------------------------------------------- /graphics/entities/high/loader-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/entities/high/loader-shadow.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/beltbox-icon-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/beltbox-icon-base.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/beltbox-icon-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/beltbox-icon-mask.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/loader-icon-base.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/loader-icon-base.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/loader-icon-mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/loader-icon-mask.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/stacking-arrow-d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/stacking-arrow-d.png -------------------------------------------------------------------------------- /graphics/icons/mipmaps/stacking-arrow-u.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/mipmaps/stacking-arrow-u.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-d-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-d-128.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-d-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-d-32.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-d-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-d-64.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-u-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-u-128.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-u-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-u-32.png -------------------------------------------------------------------------------- /graphics/icons/square/arrow-u-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/arrow-u-64.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-base-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-base-128.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-base-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-base-32.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-base-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-base-64.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-mask-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-mask-128.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-mask-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-mask-32.png -------------------------------------------------------------------------------- /graphics/icons/square/beltbox-icon-mask-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/beltbox-icon-mask-64.png -------------------------------------------------------------------------------- /graphics/icons/square/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/blank.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-base-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-base-128.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-base-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-base-32.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-base-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-base-64.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-mask-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-mask-128.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-mask-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-mask-32.png -------------------------------------------------------------------------------- /graphics/icons/square/loader-icon-mask-64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/loader-icon-mask-64.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-advanced-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-advanced-circuit.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-battery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-battery.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-coal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-coal.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-copper-cable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-copper-cable.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-copper-ore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-copper-ore.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-copper-plate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-copper-plate.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-electronic-circuit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-electronic-circuit.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-iron-gear-wheel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-iron-gear-wheel.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-iron-ore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-iron-ore.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-iron-plate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-iron-plate.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-iron-stick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-iron-stick.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-plastic-bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-plastic-bar.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-processing-unit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-processing-unit.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-solid-fuel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-solid-fuel.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-steel-plate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-steel-plate.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-stone-brick.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-stone-brick.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-stone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-stone.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-sulfur.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-sulfur.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-tungsten-ore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-tungsten-ore.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-uranium-235.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-uranium-235.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-uranium-238.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-uranium-238.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-uranium-ore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-uranium-ore.png -------------------------------------------------------------------------------- /graphics/icons/square/stacked-wood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/graphics/icons/square/stacked-wood.png -------------------------------------------------------------------------------- /info.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "deadlock-beltboxes-loaders", 3 | "version": "2.6.0", 4 | "title": "Deadlock's Stacking Beltboxes & Compact Loaders", 5 | "author": "Deadlock989, Shane Madden, MasterBuilder", 6 | "homepage": "https://forums.factorio.com/viewtopic.php?f=94&t=57264", 7 | "dependencies": [ 8 | "base >= 2.0", 9 | "? ReStack", 10 | "? space-age" 11 | ], 12 | "description": "Adds minimalist 1x1 loaders and stacking beltboxes for 5x belt compression for ores, plates and some intermediate products", 13 | "factorio_version": "2.0" 14 | } 15 | -------------------------------------------------------------------------------- /locale/en/deadlock-beltboxes-loaders.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | transport-belt-loader=Compact loader 3 | fast-transport-belt-loader=Fast compact loader 4 | express-transport-belt-loader=Express compact loader 5 | turbo-transport-belt-loader=Turbo compact loader 6 | transport-belt-beltbox=Stacking beltbox 7 | fast-transport-belt-beltbox=Fast stacking beltbox 8 | express-transport-belt-beltbox=Express stacking beltbox 9 | turbo-transport-belt-beltbox=Turbo stacking beltbox 10 | 11 | [entity-description] 12 | deadlock-loader=Quickly transfers resources between belts and inventories. Rotate after placement to change input/output mode. 13 | deadlock-beltbox=Stacks/unstacks some resources and products, enabling 5x compression on belts. 14 | 15 | [item-name] 16 | deadlock-stacking-stack=__1__ (stack of __2__) 17 | 18 | [recipe-name] 19 | deadlock-stacking-stack=__1__ (stack) 20 | deadlock-stacking-unstack=__1__ (unstack) 21 | 22 | [technology-name] 23 | deadlock-stacking=Stacking 24 | 25 | [technology-description] 26 | deadlock-stacking=Unlocks stacking beltboxes, which can boost belt throughput for specific resources. 27 | 28 | [mod-setting-name] 29 | deadlock-enable-beltboxes=Enable Beltboxes 30 | deadlock-enable-loaders=Enable Loaders 31 | deadlock-stacking-auto-unstack=Auto unstack 32 | deadlock-stacking-hide-unstacking=Hide unstacking recipes 33 | deadlock-loaders-snap-to-belts=Snap loaders to belts 34 | deadlock-loaders-snap-to-inventories=Snap loaders to inventories 35 | deadlock-stacking-batch-stacking=Batch stacking 36 | deadlock-stacking-show-alt-info=Show alt-mode icons on beltboxes 37 | deadlock-strict-fast-replace-beltboxes=Strict beltbox fast replace 38 | deadlock-strict-fast-replace-loaders=Strict loader fast replace 39 | deadlock-stack-size=Stack Size 40 | 41 | [mod-setting-description] 42 | deadlock-stacking-auto-unstack=Automatically unstack any stacked items picked up from the ground or belts. 43 | deadlock-stacking-hide-unstacking=Removes unstacking recipes from the player crafting tab. This prevents you from "hand-unstacking" but removes a lot of clutter. 44 | deadlock-loaders-snap-to-belts=Loaders will automatically set their mode and rotation to match adjacent belts (and inventories on their belt side) when placed 45 | deadlock-loaders-snap-to-inventories=Loaders will automatically input into inventories they're facing toward or away from when placed 46 | deadlock-stacking-batch-stacking=Beltboxes will stack and unstack in batches of 4, loading belts evenly and increasing throughput with extremely high speed modded belts 47 | deadlock-stacking-show-alt-info=Shows or hides the recipe icon displayed on beltboxes in alt-mode. 48 | deadlock-strict-fast-replace-beltboxes=Prevent beltboxes from fast replacing anything but other beltboxes 49 | deadlock-strict-fast-replace-loaders=Prevent loaders from fast replacing anything but other loaders 50 | deadlock-stack-size=Set the number of items making up each stacked item. Warning: it is not recommended to change this setting for existing saved games. Stacked items will lose inventory density when this is configured to a number their stack sizes don't divide evenly by. 51 | -------------------------------------------------------------------------------- /locale/fr/fr.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | transport-belt-loader=Chargeur compact 3 | fast-transport-belt-loader=Chargeur compact rapide 4 | express-transport-belt-loader=Chargeur compact express 5 | transport-belt-beltbox=Boîte de rangement empilable 6 | fast-transport-belt-beltbox=Boîte de rangement empilable rapide 7 | express-transport-belt-beltbox=Boîte de rangement empilable express 8 | 9 | [entity-description] 10 | deadlock-loader=Transfère rapidement les ressources entre les convoyers et les stocks. Tourner après le placement pour changer le mode d’entrée / sortie. 11 | deadlock-beltbox=Empile / désempile certaines ressources et produits, permettant une compression 5x sur les convoyeurs. 12 | 13 | [item-name] 14 | deadlock-stacking-stack=__1__ (pile de __2__) 15 | 16 | [recipe-name] 17 | deadlock-stacking-stack=__1__ (empile) 18 | deadlock-stacking-unstack=__1__ (désempiler) 19 | 20 | [technology-name] 21 | deadlock-stacking=Empilement 22 | 23 | [technology-description] 24 | deadlock-stacking=Débloque les boîtes à convoyeurs empilables, ce qui peut augmenter le débit des convoyers pour des ressources spécifiques. 25 | 26 | [mod-setting-name] 27 | deadlock-enable-beltboxes=Enable Beltboxes 28 | deadlock-enable-loaders=Activer les chargeurs 29 | deadlock-stacking-auto-unstack=Désempiler automatiquement 30 | deadlock-stacking-hide-unstacking=Cacher les recettes de dépilage 31 | deadlock-loaders-snap-to-belts=Chargeurs instantanés sur les ceintures 32 | deadlock-loaders-snap-to-inventories=Aligner les chargeurs sur les stocks 33 | deadlock-stacking-batch-stacking=Empilement par lots 34 | deadlock-stacking-show-alt-info=Afficher les icônes de mode alternatif sur les boîtes à ceinture 35 | deadlock-strict-fast-replace-beltboxes=Remplacement strict de la ceinture 36 | deadlock-strict-fast-replace-loaders=Remplacement rapide du chargeur strict 37 | 38 | [mod-setting-description] 39 | deadlock-stacking-auto-unstack=Désempiler automatiquement tous les objets empilés pris sur le sol ou sur les ceintures. 40 | deadlock-stacking-hide-unstacking=Supprime les recettes de désempilage de l'onglet Fabrication du joueur. Cela vous empêche de "dépiler à la main" mais élimine beaucoup d'encombrement. 41 | deadlock-loaders-snap-to-belts=Les chargeurs définiront automatiquement leur mode et leur rotation pour correspondre aux convoyeurs adjacentes (et aux stocks situés du côté du convoyeur) une fois placées 42 | deadlock-loaders-snap-to-inventories=Les chargeurs vont automatiquement entrer dans les inventaires auxquels ils sont confrontés ou éloignés une fois placés. 43 | deadlock-stacking-batch-stacking=Les boîtes à bandes s'empilent et se désempilent par lots de 4, chargeant les convoyeurs de manière uniforme et augmentant le débit avec des convoyers modifiés à très haute vitesse 44 | deadlock-stacking-show-alt-info=Affiche ou masque l'icône de recette affichée sur les boîtes à convoyeurs en mode alt. 45 | deadlock-strict-fast-replace-beltboxes=Empêcher les boîtes à ceinture de remplacer rapidement tout ce qui est autre que les boîtes à ceinture. 46 | deadlock-strict-fast-replace-loaders=Empêcher les chargeurs de remplacer rapidement autre chose que d'autres chargeurs. 47 | -------------------------------------------------------------------------------- /locale/it/deadlock-beltboxes-loaders.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | transport-belt-loader=Caricatore compatto 3 | fast-transport-belt-loader=Caricatore compatto veloce 4 | express-transport-belt-loader=Caricatore compatto espresso 5 | transport-belt-beltbox=Impilatore 6 | fast-transport-belt-beltbox=Impilatore veloce 7 | express-transport-belt-beltbox=Impilatore espresso 8 | 9 | [entity-description] 10 | deadlock-loader=Trasferisce velocemente gli oggetti dai rulli agli inventari. Ruotalo dopo averlo piazzato per cambiare la direzione d'input/output. 11 | deadlock-beltbox=Impila/de-impila risorse e prodotti, permettendo di impilare fino a 5 oggetti assieme. 12 | 13 | [item-name] 14 | deadlock-stacking-stack=__1__ (pila di __2__) 15 | 16 | [recipe-name] 17 | deadlock-stacking-stack=__1__ (impila) 18 | deadlock-stacking-unstack=__1__ (de-impila) 19 | 20 | [technology-name] 21 | deadlock-stacking=Impilazione 22 | 23 | [technology-description] 24 | deadlock-stacking=Sblocca la possibilità di impilare oggetti, aumentando la capacità trasportabile di specifiche risorse. 25 | 26 | [mod-setting-name] 27 | deadlock-enable-beltboxes=Abilita impilatori 28 | deadlock-enable-loaders=Abilita caricatori 29 | deadlock-stacking-auto-unstack=De-impila automaticamente 30 | deadlock-stacking-hide-unstacking=Nascondi ricette di de-impilazione 31 | deadlock-loaders-snap-to-belts=Posiziona automaticamente i caricatori ai nastri 32 | deadlock-loaders-snap-to-inventories=Posiziona automaticamente i caricatori agli inventari 33 | deadlock-stacking-batch-stacking=Raggruppa impilazione 34 | deadlock-stacking-show-alt-info=Mostra con alt icone e impilatori 35 | deadlock-strict-fast-replace-beltboxes=Previeni ripiazzamento per impilatori 36 | deadlock-strict-fast-replace-loaders=Previeni ripiazzamento per i caricatori 37 | deadlock-stack-size=Dimensione delle pile 38 | 39 | [mod-setting-description] 40 | deadlock-stacking-auto-unstack=De-impila automaticamente ogni oggetto staccato che viene inserito in un impilatore. 41 | deadlock-stacking-hide-unstacking=Rimuovi le ricette di de-impilazione dalla schermata del giocatore. Previene anche che il giocatore possa de-impilare a mano. 42 | deadlock-loaders-snap-to-belts=I caricatori settano la loro direzione automaticamente verso i nastri (e inventari adiacenti ai nastri) quando piazzati 43 | deadlock-loaders-snap-to-inventories=I caricatori settano la loro direzione automaticamente verso gli inventari adiacenti quando piazzati 44 | deadlock-stacking-batch-stacking=Gli impilatori possono impilare gruppi da 4, aumentando tremendamente la capienza dei nastri 45 | deadlock-stacking-show-alt-info=Mostra e nasconde le icone delle ricette degli inseritori con alt. 46 | deadlock-strict-fast-replace-beltboxes=Previene il ripiazzamento rapido per gli impilatori 47 | deadlock-strict-fast-replace-loaders=Previene il ripiazzamento per i caricatori 48 | deadlock-stack-size=Imposta il numero di oggetti che possono essere impilati in uno. Attenzione: non è raccomandato cambiare questa impostazione, per salvataggi già esistenti. Potrebbe creare delle perdite di oggetti. 49 | -------------------------------------------------------------------------------- /locale/ja/deadlock-beltboxes-loaders.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | transport-belt-loader=コンパクトローダー 3 | fast-transport-belt-loader=高速コンパクトローダー 4 | express-transport-belt-loader=超高速コンパクトローダー 5 | transport-belt-beltbox=スタックベルトボックス 6 | fast-transport-belt-beltbox=高速スタックベルトボックス 7 | express-transport-belt-beltbox=超高速スタックベルトボックス 8 | 9 | [entity-description] 10 | deadlock-loader=ベルトとインベントリ間で資源や製品を素早く転送します。配置後に回転させて入出力モードを変更します。 11 | deadlock-beltbox=いくつかの資源や製品をまとめたりばらしたりしてベルトを5倍に圧縮します。 12 | 13 | [item-name] 14 | deadlock-stacking-stack=__1__ (__2__個のスタック) 15 | 16 | [recipe-name] 17 | deadlock-stacking-stack=__1__ (スタック) 18 | deadlock-stacking-unstack=__1__ (アンスタック) 19 | 20 | [technology-name] 21 | deadlock-stacking=スタック 22 | 23 | [technology-description] 24 | deadlock-stacking=スタックベルトボックスを解除します。特定の資源のベルトスループットが向上します。 25 | 26 | [mod-setting-name] 27 | deadlock-enable-beltboxes=スタックベルトボックスを有効にする 28 | deadlock-enable-loaders=ローダーを有効にする 29 | deadlock-stacking-auto-unstack=自動アンスタック 30 | deadlock-stacking-hide-unstacking=アンスタックレシピを隠す 31 | deadlock-loaders-snap-to-belts=ローダーをベルトに合わせる 32 | deadlock-loaders-snap-to-inventories=ローダーをインベントリに合わせる 33 | deadlock-stacking-batch-stacking=バッチスタック 34 | deadlock-stacking-show-alt-info=ベルトボックスのAltモードアイコン表示 35 | deadlock-strict-fast-replace-beltboxes=ベルトボックスの高速置換抑止 36 | deadlock-strict-fast-replace-loaders=ローダーの高速置換抑止 37 | deadlock-stack-size=スタック数 38 | 39 | [mod-setting-description] 40 | deadlock-stacking-auto-unstack=地面やベルトからスタックアイテムを拾った際に自動的にアンスタックします。 41 | deadlock-stacking-hide-unstacking=プレイヤーの製作タブからアンスタックレシピを削除します。手動でアンスタックできなくなりますが乱雑なものを削除できます。 42 | deadlock-loaders-snap-to-belts=配置時にローダーは隣接するベルト(とベルトのそばのインベントリ)に合うようにモードと向きを自動的に設定します。 43 | deadlock-loaders-snap-to-inventories=配置時にローダーは正面か反対向きのインベントリに自動的に入力します。 44 | deadlock-stacking-batch-stacking=ベルトボックスは4つずつスタックまたはアンスタックされ、ベルトに均等に積み込まれて非常に高速な改造ベルトによりスループットが向上します。 45 | deadlock-stacking-show-alt-info=Altモードでベルトボックスに表示されるレシピアイコンを表示または非表示にします。 46 | deadlock-strict-fast-replace-beltboxes=ベルトボックスが他のベルトボックス以外のものに高速置換されないようにします。 47 | deadlock-strict-fast-replace-loaders=ローダーが他のローダー以外のものに高速置換されないようにします。 48 | deadlock-stack-size=スタックアイテムの構成数を設定します。\n警告: 既存のセーブゲームでこの設定を変更することは推奨しません。この値がスタックサイズを割りきれない値に設定された場合、インベントリの密度を失います。 49 | -------------------------------------------------------------------------------- /locale/ru/deadlock-beltboxes-loaders.cfg: -------------------------------------------------------------------------------- 1 | [entity-name] 2 | transport-belt-loader=Компактный погрузчик 3 | fast-transport-belt-loader=Быстрый компактный погрузчик 4 | express-transport-belt-loader=Экспресс-компактный погрузчик 5 | transport-belt-beltbox=Конвейерный упаковщик 6 | fast-transport-belt-beltbox=Быстрый конвейерный упаковщик 7 | express-transport-belt-beltbox=Экспресс-конвейерный упаковщик 8 | 9 | [entity-description] 10 | deadlock-loader=Быстро перемещает ресурсы между лентами и инвентарями. Поверните после установки, чтобы изменить режим входа/выхода. 11 | deadlock-beltbox=Упаковывает/распаковывает некоторые ресурсы и предметы, позволяя пятикратное сжатие на конвейерах. 12 | 13 | [item-name] 14 | deadlock-stacking-stack=__1__ (пачка из __2__) 15 | 16 | [recipe-name] 17 | deadlock-stacking-stack=__1__ (упаковать) 18 | deadlock-stacking-unstack=__1__ (распаковать) 19 | 20 | [technology-name] 21 | deadlock-stacking=Упаковка 22 | 23 | [technology-description] 24 | deadlock-stacking=Разблокирует конвейерные упаковщики, которые могут улучшить пропускную способность конвейеров для определённых ресурсов. 25 | 26 | [mod-setting-name] 27 | deadlock-enable-beltboxes=Включить конвейерные упаковщики 28 | deadlock-enable-loaders=Включить погрузчики 29 | deadlock-stacking-auto-unstack=Автоматическая распаковка 30 | deadlock-stacking-hide-unstacking=Скрыть рецепты распаковки 31 | deadlock-loaders-snap-to-belts=Привязывать погрузчики к конвейерам 32 | deadlock-loaders-snap-to-inventories=Привязывать погрузчики к инвентарям 33 | deadlock-stacking-batch-stacking=Партийное сжатие 34 | deadlock-stacking-show-alt-info=Показывать иконки режима дополнительной информации на конвейерных упаковщиках 35 | deadlock-strict-fast-replace-beltboxes=Ограничить быстрое замещение конвейерных упаковщиков 36 | deadlock-strict-fast-replace-loaders=Ограничить быстрое замещение погрузчиков 37 | deadlock-stack-size=Размер пачки 38 | 39 | [mod-setting-description] 40 | deadlock-stacking-auto-unstack=Автоматически распаковывать упакованные предметы, поднятые с замли или конвейера. 41 | deadlock-stacking-hide-unstacking=Убирает рецепты распаковки из меню крафта игрока. Лишает фозможности ручной распаковки, но убирает кучу беспорядка. 42 | deadlock-loaders-snap-to-belts=Погрузчики будут автоматически изменять свой режим и ориентацию в зависимости от соседних конвейеров и инвентарей при установке 43 | deadlock-loaders-snap-to-inventories=Погрузчики будут автоматически класть предметы в инвентари, на которые направлены при установке 44 | deadlock-stacking-batch-stacking=Конвейерные упаковщики будут упаковывать и распаковывать партиями по 4, распределяя нагрузку на конвейеры и увеличивая пропускную способность с экстремальными скоростями конвейеров из модов 45 | deadlock-stacking-show-alt-info=Показывать иконку текущего рецепта на конвейерных упаковщиках в режиме дополнительной информации. 46 | deadlock-strict-fast-replace-beltboxes=Предотвратить быстрое замещение конвейерными упаковщиками чего угодно, кроме других конвейерных упаковщиков 47 | deadlock-strict-fast-replace-loaders=Предотвратить быстрое замещение погрузчиками чего угодно, кроме других погрузчиков 48 | deadlock-stack-size=Количество предметов в одном упакованном предмете. Внимание: не рекомендуется менять эту настройку в существующих сохранениях. Упакованные предметы потеряют плотность инвентаря, если их размер стака не делится на заданное число нацело. 49 | -------------------------------------------------------------------------------- /migrations/deadlock-beltboxes-loaders_2.0.2.json: -------------------------------------------------------------------------------- 1 | { 2 | "item": [ 3 | ["deadlock-stack-raw-wood", "deadlock-stack-wood"] 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /migrations/deadlock-beltboxes-loaders_2.0.2.lua: -------------------------------------------------------------------------------- 1 | for _, force in pairs(game.forces) do 2 | force.reset_technologies() 3 | for tech_name, technology in pairs(force.technologies) do 4 | if technology.researched then 5 | for _, effect in pairs(technology.prototype.effects) do 6 | if effect.type == "unlock-recipe" then 7 | force.recipes[effect.recipe].enabled = true 8 | end 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /migrations/logistics-recipes.lua: -------------------------------------------------------------------------------- 1 | for _, force in pairs(game.forces) do 2 | force.reset_technologies() 3 | for tech_name, technology in pairs(force.technologies) do 4 | if technology.researched then 5 | for _, effect in pairs(technology.prototype.effects) do 6 | if effect.type == "unlock-recipe" then 7 | force.recipes[effect.recipe].enabled = true 8 | end 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /prototypes/create_beltbox.lua: -------------------------------------------------------------------------------- 1 | local DBL = require("prototypes.shared") 2 | 3 | -- average a colour with off-white, to get a brighter contrast colour for lamps and lights 4 | local function brighter_colour(c) 5 | local w = 240 6 | return { r = math.floor((c.r + w)/2), g = math.floor((c.g + w)/2), b = math.floor((c.b + w)/2) } 7 | end 8 | 9 | local function create_beltbox_entity(tier_table) 10 | local crafting_speed = data.raw["transport-belt"][tier_table.transport_belt].speed * 32 11 | local entity = { 12 | type = "furnace", 13 | name = tier_table.beltbox, 14 | localised_description = {"entity-description.deadlock-beltbox"}, 15 | icons = { 16 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/beltbox-icon-base.png" }, 17 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/beltbox-icon-mask.png", tint = tier_table.colour }, 18 | }, 19 | icon_size = 64, 20 | icon_mipmaps = 4, 21 | flags = { "placeable-neutral", "placeable-player", "player-creation" }, 22 | graphics_set = { 23 | animation = { 24 | layers = { 25 | { 26 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/beltbox-base.png", 27 | animation_speed = 1 / crafting_speed, 28 | priority = "high", 29 | frame_count = 60, 30 | line_length = 10, 31 | height = 96, 32 | scale = 0.5, 33 | shift = {0, 0}, 34 | width = 96 35 | }, 36 | { 37 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/beltbox-mask.png", 38 | animation_speed = 1 / crafting_speed, 39 | priority = "high", 40 | repeat_count = 60, 41 | height = 96, 42 | scale = 0.5, 43 | shift = {0, 0}, 44 | width = 96, 45 | tint = tier_table.colour, 46 | }, 47 | { 48 | draw_as_shadow = true, 49 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/beltbox-shadow.png", 50 | animation_speed = 1 / crafting_speed, 51 | frame_count = 60, 52 | line_length = 10, 53 | height = 96, 54 | scale = 0.5, 55 | shift = {0.5, 0}, 56 | width = 144 57 | }, 58 | }, 59 | }, 60 | working_visualisations = { 61 | { 62 | animation = { 63 | animation_speed = 1 / crafting_speed, 64 | blend_mode = "additive", 65 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/beltbox-working.png", 66 | frame_count = 30, 67 | line_length = 10, 68 | height = 96, 69 | priority = "high", 70 | scale = 0.5, 71 | tint = brighter_colour(tier_table.colour), 72 | width = 96 73 | }, 74 | light = { 75 | color = brighter_colour(tier_table.colour), 76 | intensity = 0.4, 77 | size = 3, 78 | shift = {0, 0.25}, 79 | }, 80 | }, 81 | } 82 | }, 83 | dying_explosion = "explosion", 84 | corpse = "small-remnants", 85 | minable = {hardness = 0.2, mining_time = 0.5, result = tier_table.beltbox_item or tier_table.beltbox}, 86 | module_specification = { module_slots = 0, module_info_icon_shift = {0,0.25} }, 87 | allowed_effects = { "consumption" }, 88 | max_health = 180, 89 | corpse = "small-remnants", 90 | collision_box = {{-0.2, -0.2}, {0.2, 0.2}}, 91 | selection_box = {{-0.5, -0.5}, {0.5, 0.5}}, 92 | drawing_box = {{-0.5, -0.5}, {0.5, 0.5}}, 93 | result_inventory_size = 1, 94 | source_inventory_size = 1, 95 | crafting_categories = {"stacking", "unstacking"}, 96 | crafting_speed = crafting_speed, 97 | energy_source = { 98 | type = "electric", 99 | emissions_per_minute = {pollution = 3 * 0.03125 / data.raw["transport-belt"][tier_table.transport_belt].speed}, 100 | usage_priority = "secondary-input", 101 | drain = "15kW", 102 | }, 103 | -- 90kW for tier 1, base the rest on relative speed 104 | energy_usage = string.format("%dkW", math.floor((data.raw["transport-belt"][tier_table.transport_belt].speed / 0.03125) * 90)), 105 | resistances = { 106 | { 107 | type = "fire", 108 | percent = 50 109 | }, 110 | }, 111 | vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 1.0 }, 112 | working_sound = { 113 | match_speed_to_activity = true, 114 | idle_sound = { 115 | filename = "__base__/sound/idle1.ogg", 116 | volume = 0.6 117 | }, 118 | sound = { 119 | filename = "__deadlock-beltboxes-loaders__/sounds/fan.ogg", 120 | volume = 1.0 121 | }, 122 | max_sounds_per_type = 3, 123 | }, 124 | show_recipe_icon = settings.startup["deadlock-stacking-show-alt-info"].value, 125 | } 126 | if settings.startup["deadlock-strict-fast-replace-beltboxes"].value then 127 | entity.fast_replaceable_group = "deadlock-beltbox" 128 | else 129 | entity.fast_replaceable_group = "transport-belt" 130 | end 131 | return entity 132 | end 133 | 134 | local function create_beltbox_item(tier_table) 135 | local item = { 136 | type = "item", 137 | name = tier_table.beltbox_item or tier_table.beltbox, 138 | localised_description = {"entity-description.deadlock-beltbox"}, 139 | icons = { 140 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/beltbox-icon-base.png" }, 141 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/beltbox-icon-mask.png", tint = tier_table.colour }, 142 | }, 143 | icon_size = 64, 144 | icon_mipmaps = 4, 145 | stack_size = 50, 146 | flags = {}, 147 | place_result = tier_table.beltbox, 148 | group = "logistics", 149 | subgroup = "beltboxes", 150 | order = string.format("b%s%s", (tier_table.order or tier_table.loader), "-deadlock-beltbox"), 151 | } 152 | return item 153 | end 154 | 155 | local function create_beltbox_recipe(tier_table) 156 | local recipe = { 157 | type = "recipe", 158 | name = tier_table.beltbox_recipe or tier_table.beltbox, 159 | localised_description = {"entity-description.deadlock-beltbox"}, 160 | category = tier_table.beltbox_category, 161 | group = "logistics", 162 | subgroup = "beltboxes", 163 | order = string.format("b%s%s", (tier_table.order or tier_table.loader), "-deadlock-beltbox"), 164 | enabled = false, 165 | ingredients = tier_table.beltbox_ingredients, 166 | results = {{type = "item", name = tier_table.beltbox_item or tier_table.beltbox, amount = 1}}, 167 | energy_required = 3.0, 168 | } 169 | if not tier_table.beltbox_technology then 170 | recipe.enabled = true 171 | end 172 | return recipe 173 | end 174 | 175 | local function create_beltbox_technology(tier_table) 176 | local tech = table.deepcopy(data.raw.technology[tier_table.technology]) 177 | tech.effects = { 178 | { 179 | type = "unlock-recipe", 180 | recipe = tier_table.beltbox_recipe or tier_table.beltbox, 181 | } 182 | } 183 | tech.icons = { 184 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/square/beltbox-icon-base-128.png", icon_size = 128 }, -- 1.1 appears to be defaulting to 256 185 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/square/beltbox-icon-mask-128.png", icon_size = 128, tint = tier_table.colour }, -- 1.1 appears to be defaulting to 256 186 | } 187 | tech.name = tier_table.beltbox_technology 188 | tech.unit.count = tech.unit.count * 1.5 189 | tech.prerequisites = {tier_table.technology} 190 | tech.upgrade = false 191 | return tech 192 | end 193 | 194 | function DBL.create_beltbox(tier_table) 195 | DBL.debug(string.format("Generating beltbox for tier %s", tier_table.transport_belt)) 196 | data:extend({ 197 | create_beltbox_entity(tier_table), 198 | create_beltbox_item(tier_table), 199 | create_beltbox_recipe(tier_table), 200 | }) 201 | if tier_table.technology and tier_table.beltbox_technology then 202 | DBL.debug(string.format("Creating beltbox tech %s", tier_table.beltbox_technology)) 203 | if data.raw.technology[tier_table.beltbox_technology] then 204 | table.insert(data.raw.technology[tier_table.beltbox_technology].effects, 2, { 205 | type = "unlock-recipe", 206 | recipe = tier_table.beltbox_recipe or tier_table.beltbox, 207 | }) 208 | else 209 | data:extend({ 210 | create_beltbox_technology(tier_table) 211 | }) 212 | DBL.BELTBOX_TECHS[tier_table.beltbox_technology] = data.raw.technology[tier_table.beltbox_technology] 213 | end 214 | end 215 | end 216 | -------------------------------------------------------------------------------- /prototypes/create_loader.lua: -------------------------------------------------------------------------------- 1 | local DBL = require("prototypes.shared") 2 | 3 | local function create_loader_belt_component(source) 4 | local component = { 5 | filename = source.filename, 6 | width = source.width, 7 | height = source.height, 8 | line_length = source.line_length, 9 | frame_count = source.frame_count, 10 | y = source.y, 11 | scale = source.scale, 12 | priority = "extra-high", 13 | flags = { "no-crop", "low-object" }, 14 | } 15 | return component 16 | end 17 | 18 | local function create_loader_entity(tier_table) 19 | local entity = {} 20 | entity.type = "loader-1x1" 21 | entity.name = tier_table.loader 22 | entity.localised_description = {"entity-description.deadlock-loader"} 23 | entity.icons = { 24 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/loader-icon-base.png" }, 25 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/loader-icon-mask.png", tint = tier_table.colour }, 26 | } 27 | entity.icon_size = 64 28 | entity.icon_mipmaps = 4 29 | entity.flags = {"placeable-neutral", "player-creation"} 30 | entity.vehicle_impact_sound = { filename = "__base__/sound/car-metal-impact.ogg", volume = 1.0 } 31 | entity.open_sound = { filename = "__base__/sound/wooden-chest-open.ogg", volume = 1.0 } 32 | entity.close_sound = { filename = "__base__/sound/wooden-chest-close.ogg", volume = 1.0 } 33 | entity.corpse = "small-remnants" 34 | entity.collision_box = { {-0.26, -0.26}, {0.26, 0.26} } -- 1.1 requires min of 0.5 width 35 | entity.collision_mask = {layers = {item = true, object = true, player = true, water_tile = true, transport_belt = true, meltable = true}} 36 | entity.selection_box = { {-0.5, -0.5}, {0.5, 0.5} } 37 | entity.minable = { hardness = 0.2, mining_time = 0.5, result = tier_table.loader_item or tier_table.loader} 38 | entity.max_health = 170 39 | entity.resistances = {{type = "fire", percent = 60 }} 40 | entity.belt_distance = 0.5 41 | entity.container_distance = 1 42 | entity.belt_length = 0.5 43 | entity.filter_count = 5 44 | entity.animation_speed_coefficient = 32 45 | if settings.startup["deadlock-strict-fast-replace-loaders"].value then 46 | entity.fast_replaceable_group = "deadlock-loader" 47 | else 48 | entity.fast_replaceable_group = "transport-belt" 49 | end 50 | entity.speed = data.raw["transport-belt"][tier_table.transport_belt].speed 51 | entity.structure = { 52 | back_patch = { 53 | sheet = { 54 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-back.png", 55 | height = 96, 56 | priority = "extra-high", 57 | width = 96, 58 | scale = 0.5, 59 | shift = { 0, 0 }, 60 | }, 61 | }, 62 | direction_in = { 63 | sheets = { 64 | { 65 | draw_as_shadow = true, 66 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-shadow.png", 67 | height = 96, 68 | priority = "medium", 69 | width = 144, 70 | scale = 0.5, 71 | shift = { 0.5, 0 }, 72 | }, 73 | { 74 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-base.png", 75 | height = 96, 76 | priority = "extra-high", 77 | width = 96, 78 | scale = 0.5, 79 | shift = { 0, 0 }, 80 | }, 81 | { 82 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-mask.png", 83 | height = 96, 84 | priority = "extra-high", 85 | width = 96, 86 | scale = 0.5, 87 | tint = tier_table.colour, 88 | shift = { 0, 0 }, 89 | }, 90 | }, 91 | }, 92 | direction_out = { 93 | sheets = { 94 | { 95 | draw_as_shadow = true, 96 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-shadow.png", 97 | height = 96, 98 | priority = "medium", 99 | width = 144, 100 | scale = 0.5, 101 | shift = { 0.5, 0 }, 102 | }, 103 | { 104 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-base.png", 105 | height = 96, 106 | priority = "extra-high", 107 | width = 96, 108 | scale = 0.5, 109 | shift = { 0, 0 }, 110 | y = 96, 111 | }, 112 | { 113 | filename = "__deadlock-beltboxes-loaders__/graphics/entities/high/loader-mask.png", 114 | height = 96, 115 | priority = "extra-high", 116 | width = 96, 117 | scale = 0.5, 118 | shift = { 0, 0 }, 119 | tint = tier_table.colour, 120 | y = 96 121 | }, 122 | }, 123 | } 124 | } 125 | -- copy belt textures from the belt, not the loader 126 | if data.raw["transport-belt"][tier_table.transport_belt].belt_animation_set then 127 | -- new style animation set 128 | entity.belt_animation_set = data.raw["transport-belt"][tier_table.transport_belt].belt_animation_set 129 | else 130 | -- old style, copy components 131 | for _, bc in ipairs(DBL.BELT_COMPONENTS) do 132 | if entity[bc] and data.raw["transport-belt"][tier_table.transport_belt][bc] then 133 | entity[bc] = create_loader_belt_component(data.raw["transport-belt"][tier_table.transport_belt][bc]) 134 | end 135 | end 136 | end 137 | entity.structure_render_layer = "object" 138 | return entity 139 | end 140 | 141 | local function create_loader_item(tier_table) 142 | local item = { 143 | type = "item", 144 | name = tier_table.loader_item or tier_table.loader, 145 | localised_description = {"entity-description.deadlock-loader"}, 146 | icons = { 147 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/loader-icon-base.png" }, 148 | { icon = "__deadlock-beltboxes-loaders__/graphics/icons/mipmaps/loader-icon-mask.png", tint = tier_table.colour }, 149 | }, 150 | icon_size = 64, 151 | icon_mipmaps = 4, 152 | stack_size = 50, 153 | flags = {}, 154 | place_result = tier_table.loader, 155 | group = "logistics", 156 | subgroup = "loaders", 157 | order = string.format("a%s%s", (tier_table.order or tier_table.loader), "-deadlock-loader"), 158 | } 159 | return item 160 | end 161 | 162 | local function create_loader_recipe(tier_table) 163 | local recipe = { 164 | type = "recipe", 165 | name = tier_table.loader_recipe or tier_table.loader, 166 | localised_description = {"entity-description.deadlock-loader"}, 167 | category = tier_table.loader_category, 168 | group = "logistics", 169 | subgroup = "loaders", 170 | order = string.format("a%s%s", (tier_table.order or tier_table.loader), "-deadlock-loader"), 171 | enabled = false, 172 | ingredients = tier_table.loader_ingredients, 173 | results = {{type = "item", name = tier_table.loader_item or tier_table.loader, amount = 1}}, 174 | energy_required = 2.0, 175 | } 176 | if not tier_table.technology then 177 | recipe.enabled = true 178 | end 179 | return recipe 180 | end 181 | 182 | function DBL.create_loader(tier_table) 183 | DBL.debug(string.format("Generating loader for tier %s", tier_table.transport_belt)) 184 | data:extend({ 185 | create_loader_item(tier_table), 186 | create_loader_entity(tier_table), 187 | create_loader_recipe(tier_table), 188 | }) 189 | -- insert the loader recipe into logistics unlock 190 | if tier_table.technology then 191 | local tech = data.raw.technology[tier_table.technology] 192 | if not tech then 193 | DBL.log_error(string.format("Bad tech specified for loader, %s", tier_table.technology)) 194 | return 195 | end 196 | DBL.debug(string.format("Adding loader to tech %s", tier_table.technology)) 197 | table.insert(tech.effects, 198 | { 199 | type = "unlock-recipe", 200 | recipe = tier_table.loader_recipe or tier_table.loader, 201 | } 202 | ) 203 | end 204 | end 205 | -------------------------------------------------------------------------------- /prototypes/create_stack.lua: -------------------------------------------------------------------------------- 1 | local DBL = require("prototypes.shared") 2 | 3 | -- multiply a number with a unit (kJ, kW etc) at the end 4 | local function multiply_number_unit(property, mult) 5 | local value, unit 6 | value = string.match(property, "%d+") 7 | if string.match(property, "%d+%.%d+") then -- catch floats 8 | value = string.match(property, "%d+%.%d+") 9 | end 10 | unit = string.match(property, "%a+") 11 | if unit == nil then 12 | return value * mult 13 | else 14 | return ((value * mult) .. unit) 15 | end 16 | end 17 | 18 | local function get_group(item, item_type) 19 | local g = data.raw["item-group"][data.raw["item-subgroup"][data.raw[item_type][item].subgroup].group].name 20 | if not g then 21 | g = "intermediate-products" 22 | end 23 | return g 24 | end 25 | 26 | local function get_localised_name(item_name) 27 | if data.raw.item[item_name] and data.raw.item[item_name].localised_name then 28 | return data.raw.item[item_name].localised_name 29 | else 30 | return {"item-name."..item_name} 31 | end 32 | end 33 | 34 | local items_to_update = {} 35 | function DBL.create_stacked_item(item_name, item_type, graphic_path, icon_size, stack_size, mipmap_levels) 36 | DBL.debug(string.format("Creating stacked item: %s", item_name)) 37 | local temp_icons, stacked_icons --, this_fuel_category, this_fuel_acceleration_multiplier, this_fuel_top_speed_multiplier, this_fuel_value, this_fuel_emissions_multiplier 38 | if graphic_path then 39 | stacked_icons = { { icon = graphic_path, icon_size = icon_size, icon_mipmaps = mipmap_levels } } 40 | else 41 | local base_item = data.raw[item_type][item_name] 42 | -- Icons has priority over icon, check for icons definition first 43 | if base_item.icons then 44 | temp_icons = table.deepcopy(base_item.icons) 45 | -- We've fetched the icons, check icon_size is present in each layer, and if not, assign it 46 | -- No need to check if base_item.icon_size exists, because if it's not defined there and not defined here, Factorio itself will not start 47 | for _, icons_layer in pairs(temp_icons) do 48 | if not icons_layer.icon_size then icons_layer.icon_size = base_item.icon_size end 49 | end 50 | -- If no icons field, look for icon definition 51 | elseif base_item.icon then 52 | if not base_item.icon_size then 53 | DBL.log_error(string.format("Can't create layered icon for item (%s), base item defines icon but no icon_size", item_name)) 54 | return 55 | end 56 | temp_icons = { { icon = base_item.icon, icon_size = base_item.icon_size, icon_mipmaps = base_item.icon_mipmaps } } 57 | else 58 | DBL.log_error(string.format("Can't create stacks for item with no icon properties (%s)", item_name)) 59 | return 60 | end 61 | DBL.log_warning(string.format("creating layered stack icon (%s), this is %dx more rendering effort than a custom icon!", item_name, 1+(#temp_icons*3))) 62 | stacked_icons = { { icon = "__deadlock-beltboxes-loaders__/graphics/icons/square/blank.png", scale = 1, icon_size = 32 } } 63 | for i = 1, -1, -1 do 64 | for _,layer in pairs(temp_icons) do 65 | layer.scale = 0.85 * 32/layer.icon_size 66 | layer.shift = {0, i*3} 67 | table.insert(stacked_icons, table.deepcopy(layer)) 68 | end 69 | end 70 | end 71 | data:extend({ 72 | { 73 | type = "item", 74 | name = string.format("deadlock-stack-%s", item_name), 75 | localised_name = {"item-name.deadlock-stacking-stack", get_localised_name(item_name), tostring(stack_size)}, 76 | icons = stacked_icons, 77 | stack_size = math.floor(data.raw[item_type][item_name].stack_size/stack_size), 78 | flags = {}, 79 | subgroup = string.format("stacks-%s", get_group(item_name, item_type)), 80 | order = DBL.item_order[item_name], 81 | allow_decomposition = false, 82 | } 83 | }) 84 | items_to_update[string.format("deadlock-stack-%s", item_name)] = { 85 | item_name = item_name, 86 | item_type = item_type, 87 | } 88 | DBL.debug(string.format("Created stacked item: %s", item_name)) 89 | end 90 | 91 | function DBL.deferred_stacked_item_updates() 92 | for stacked_item_name, item_table in pairs(items_to_update) do 93 | local item_name = item_table.item_name 94 | local item_type = item_table.item_type 95 | if data.raw[item_type][item_name] then 96 | local stack_size = deadlock.get_item_stack_density(item_name, item_type) 97 | data.raw.item[stacked_item_name].subgroup = string.format("stacks-%s", get_group(item_name, item_type)) 98 | data.raw.item[stacked_item_name].stack_size = math.floor(data.raw[item_type][item_name].stack_size/stack_size) 99 | data.raw.item[stacked_item_name].localised_name = {"item-name.deadlock-stacking-stack", get_localised_name(item_name), tostring(stack_size)} 100 | -- warn when the current stack size causes a loss in inventory density for this item 101 | if data.raw[item_type][item_name].stack_size % stack_size > 0 then 102 | DBL.log_warning(string.format("Full stack density for %s is reduced to %d from source stack size %d, doesn't divide cleanly by %d", stacked_item_name, (data.raw.item[stacked_item_name].stack_size * stack_size), data.raw[item_type][item_name].stack_size, stack_size)) 103 | end 104 | if data.raw[item_type][item_name].fuel_value then 105 | data.raw.item[stacked_item_name].fuel_category = data.raw[item_type][item_name].fuel_category 106 | data.raw.item[stacked_item_name].fuel_acceleration_multiplier = data.raw[item_type][item_name].fuel_acceleration_multiplier 107 | data.raw.item[stacked_item_name].fuel_top_speed_multiplier = data.raw[item_type][item_name].fuel_top_speed_multiplier 108 | data.raw.item[stacked_item_name].fuel_emissions_multiplier = data.raw[item_type][item_name].fuel_emissions_multiplier 109 | -- great, the fuel value is a string, with SI units. how very easy to work with 110 | -- now works with fuel values that have a decimal place 111 | data.raw.item[stacked_item_name].fuel_value = multiply_number_unit(data.raw[item_type][item_name].fuel_value, stack_size) 112 | end 113 | else 114 | DBL.log_warning("Item \""..item_name.."\" appears to have been deleted since it was added to the deferred item updates list, skipping it.") 115 | end 116 | end 117 | end 118 | 119 | -- make stacking/unstacking recipes for a base item 120 | -- Deadlock 8.6.19: no need to pass icon parameters, can be extracted from item 121 | function DBL.create_stacking_recipes(item_name, item_type, stack_size) 122 | DBL.debug(string.format("Creating recipes: %s", item_name)) 123 | local base_item = data.raw.item[string.format("deadlock-stack-%s", item_name)] 124 | local base_icons = data.raw.item[string.format("deadlock-stack-%s", item_name)].icons 125 | if not base_icons then 126 | base_icons = { { icon = base_item.icon, icon_size = base_item.icon_size, icon_mipmaps = base_item.icon_mipmaps } } 127 | end 128 | local stack_speed_modifier = stack_size / DBL.STACK_SIZE 129 | -- stacking 130 | local stack_icons = table.deepcopy(base_icons) 131 | table.insert(stack_icons, 132 | { 133 | icon = "__deadlock-beltboxes-loaders__/graphics/icons/square/arrow-d-64.png", 134 | scale = 0.25, 135 | icon_size = 64, 136 | } 137 | ) 138 | data:extend({ 139 | { 140 | type = "recipe", 141 | name = string.format("deadlock-stacks-stack-%s", item_name), 142 | localised_name = {"recipe-name.deadlock-stacking-stack", get_localised_name(item_name)}, 143 | category = "stacking", 144 | group = "intermediate-products", 145 | subgroup = data.raw.item[string.format("deadlock-stack-%s", item_name)].subgroup, 146 | order = DBL.recipe_order[item_name].."[a]", 147 | enabled = false, 148 | allow_decomposition = false, 149 | ingredients = {{type = "item", name = item_name, amount = stack_size * DBL.RECIPE_MULTIPLIER}}, 150 | results = {{type = "item", name = string.format("deadlock-stack-%s", item_name), amount = DBL.RECIPE_MULTIPLIER}}, 151 | energy_required = DBL.CRAFT_TIME * DBL.RECIPE_MULTIPLIER * stack_speed_modifier, 152 | icons = stack_icons, 153 | hidden = true, 154 | allow_as_intermediate = false, 155 | hide_from_stats = true, 156 | } 157 | }) 158 | -- unstacking 159 | local unstack_icons = table.deepcopy(base_icons) 160 | table.insert(unstack_icons, 161 | { 162 | icon = "__deadlock-beltboxes-loaders__/graphics/icons/square/arrow-u-64.png", 163 | scale = 0.25, 164 | icon_size = 64, 165 | } 166 | ) 167 | data:extend({ 168 | { 169 | type = "recipe", 170 | name = string.format("deadlock-stacks-unstack-%s", item_name), 171 | localised_name = {"recipe-name.deadlock-stacking-unstack", get_localised_name(item_name)}, 172 | category = "unstacking", 173 | group = "intermediate-products", 174 | subgroup = data.raw.item[string.format("deadlock-stack-%s", item_name)].subgroup, 175 | order = DBL.recipe_order[item_name].."[b]", 176 | enabled = false, 177 | allow_decomposition = false, 178 | ingredients = {{type = "item", name = string.format("deadlock-stack-%s", item_name), amount = DBL.RECIPE_MULTIPLIER}}, 179 | results = {{type = "item", name = item_name, amount = stack_size * DBL.RECIPE_MULTIPLIER}}, 180 | energy_required = DBL.CRAFT_TIME * DBL.RECIPE_MULTIPLIER * stack_speed_modifier, 181 | icons = unstack_icons, 182 | hidden = settings.startup["deadlock-stacking-hide-unstacking"].value, 183 | allow_as_intermediate = false, 184 | hide_from_stats = true, 185 | } 186 | }) 187 | DBL.debug(string.format("Created recipes: %s", item_name)) 188 | end 189 | 190 | -- make the stacking recipes depend on a technology 191 | function DBL.add_stacks_to_tech(item_name, target_technology) 192 | -- gather what recipes this tech currently unlocks to avoid adding duplicates 193 | local recipes = {} 194 | for _, effect in pairs(data.raw.technology[target_technology].effects) do 195 | if effect.type == "unlock-recipe" then 196 | recipes[effect.recipe] = true 197 | end 198 | end 199 | -- insert stacking recipe 200 | if recipes[string.format("deadlock-stacks-stack-%s", item_name)] then 201 | DBL.log_warning(string.format("Skipping already added tech effect for stacking %s", item_name)) 202 | else 203 | table.insert(data.raw.technology[target_technology].effects, 204 | { 205 | type = "unlock-recipe", 206 | recipe = string.format("deadlock-stacks-stack-%s", item_name), 207 | } 208 | ) 209 | end 210 | -- insert unstacking recipe 211 | if recipes[string.format("deadlock-stacks-stack-%s", item_name)] then 212 | DBL.log_warning(string.format("Skipping already added tech effect for unstacking %s", item_name)) 213 | else 214 | table.insert(data.raw.technology[target_technology].effects, 215 | { 216 | type = "unlock-recipe", 217 | recipe = string.format("deadlock-stacks-unstack-%s", item_name), 218 | } 219 | ) 220 | end 221 | DBL.debug(string.format("Added stacks for %s to tech %s", item_name, target_technology)) 222 | end 223 | -------------------------------------------------------------------------------- /prototypes/public.lua: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 2 | 3 | local DBL = require("prototypes.shared") 4 | 5 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 6 | 7 | -- table for main public interface 8 | deadlock = {} 9 | 10 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 11 | 12 | function deadlock.add_tier(tier_table) 13 | -- { 14 | -- transport_belt = string, -- mandatory, used for speed etc 15 | -- colour = table, -- recommended, default to pink 16 | -- underground_belt = string, -- mandatory unless loader_ingredients and beltbox_ingredients specified, used for recipe cost and styling if present 17 | -- splitter = string, -- optional, styling only, unused in this mod but passed through to the styling mod if it's present 18 | -- technology = string, -- recommended, logistics tech for this tier, defaults to unlocking the recipes right away (also, there will be no beltbox tech to point stacking recipes at) 19 | -- order = string, -- recommended, order string for loaders and beltboxes 20 | -- loader = string, -- optional, prototype string for the loader that'll be created, defaults to transport_belt.."-loader" 21 | -- loader_ingredients = table, -- mandatory unless underground_belt specified, used for loader recipe cost 22 | -- loader_recipe = string, -- optional, only if you need to override the recipe name (for legacy compatibility) 23 | -- loader_item = string, -- optional, only if you need to override the item name (for legacy compatibility) 24 | -- loader_category = string, -- optional, default to "crafting" but use "crafting-with-fluid" if there's fluid in the recipe 25 | -- beltbox = string, -- optional, prototype string for the beltbox that'll be created, defaults to transport_belt.."-beltbox" 26 | -- beltbox_ingredients = table, -- mandatory unless underground_belt specified, used for loader recipe cost 27 | -- beltbox_technology = string, -- optional, defaults to beltbox_name but can be overridden (vanilla use "deadlock-stacking-[1-3]" for legacy compatibility, since other mods' create() functions for stackable items likely point at these) 28 | -- beltbox_recipe = string, -- optional, only if you need to override the recipe name (for legacy compatibility) 29 | -- beltbox_item = string, -- optional, only if you need to override the item name (for legacy compatibility) 30 | -- beltbox_category = string, -- optional, default to "crafting" but use "crafting-with-fluid" if there's fluid in the recipe 31 | -- } 32 | ---- validation ---- 33 | DBL.debug("Beginning data validation for new tier") 34 | -- parent table 35 | if not tier_table then 36 | DBL.log_error("Nothing passed, a table is required") 37 | return 38 | end 39 | if type(tier_table) ~= "table" then 40 | DBL.log_error("Non-table passed, a table is required") 41 | return 42 | end 43 | -- check transport belt 44 | if not tier_table.transport_belt then 45 | DBL.log_error("Transport belt entity not specified.") 46 | return 47 | end 48 | if not data.raw["transport-belt"][tier_table.transport_belt] then 49 | DBL.log_error(string.format("Transport belt entity %s doesn't exist", tier_table.transport_belt)) 50 | return 51 | end 52 | -- check colour 53 | if not (tier_table.colour and tier_table.colour.r and tier_table.colour.g and tier_table.colour.b) then 54 | tier_table.colour = {r=1,g=0.8,b=0.8} 55 | end 56 | -- check underground_belt 57 | if tier_table.underground_belt and not data.raw["underground-belt"][tier_table.underground_belt] then 58 | DBL.log_error(string.format("Underground belt entity %s doesn't exist", tier_table.underground_belt)) 59 | return 60 | end 61 | -- check splitter 62 | if tier_table.splitter and not data.raw["splitter"][tier_table.splitter] then 63 | DBL.log_error(string.format("Splitter entity %s doesn't exist", tier_table.splitter)) 64 | return 65 | end 66 | 67 | -- check ingredients 68 | if not tier_table.underground_belt then 69 | if not tier_table.loader_ingredients then 70 | DBL.log_error(string.format("Missing ingredients table for loader for %s", tier_table.transport_belt)) 71 | return 72 | elseif type(tier_table.loader_ingredients) ~= "table" then 73 | DBL.log_error(string.format("Bad ingredients table for loader for %s", tier_table.transport_belt)) 74 | return 75 | end 76 | if not tier_table.beltbox_ingredients then 77 | DBL.log_error(string.format("Missing ingredients table for beltbox for %s", tier_table.transport_belt)) 78 | return 79 | elseif type(tier_table.beltbox_ingredients) ~= "table" then 80 | DBL.log_error(string.format("Bad ingredients table for beltbox for %s", tier_table.transport_belt)) 81 | return 82 | end 83 | end 84 | DBL.debug(string.format("Data validation completed for tier for %s", tier_table.transport_belt)) 85 | 86 | -- defaults 87 | if not tier_table.loader_ingredients then 88 | tier_table.loader_ingredients = data.raw.recipe[tier_table.underground_belt].ingredients 89 | end 90 | if not tier_table.loader_category then 91 | if data.raw.recipe[tier_table.underground_belt] then 92 | tier_table.loader_category = data.raw.recipe[tier_table.underground_belt].category 93 | else 94 | tier_table.loader_category = "crafting" 95 | end 96 | end 97 | if not tier_table.loader then 98 | tier_table.loader = string.format("%s-loader", tier_table.transport_belt) 99 | end 100 | 101 | if not tier_table.beltbox_ingredients then 102 | tier_table.beltbox_ingredients = data.raw.recipe[tier_table.underground_belt].ingredients 103 | end 104 | if not tier_table.beltbox_category then 105 | if data.raw.recipe[tier_table.underground_belt] then 106 | tier_table.beltbox_category = data.raw.recipe[tier_table.underground_belt].category 107 | else 108 | tier_table.beltbox_category = "crafting" 109 | end 110 | end 111 | if not tier_table.beltbox then 112 | tier_table.beltbox = string.format("%s-beltbox", tier_table.transport_belt) 113 | end 114 | if not tier_table.beltbox_technology then 115 | tier_table.beltbox_technology = tier_table.beltbox 116 | end 117 | 118 | -- pass to styling if present 119 | if deadlock_belt_styling then 120 | deadlock_belt_styling.add_tier(tier_table) 121 | end 122 | 123 | if settings.startup["deadlock-enable-loaders"].value then 124 | DBL.create_loader(tier_table) 125 | end 126 | if settings.startup["deadlock-enable-beltboxes"].value then 127 | DBL.create_beltbox(tier_table) 128 | end 129 | end 130 | 131 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 132 | 133 | -- return the effective stack density of an item, exposed publicly for other mods if they need in recipes etc 134 | function deadlock.get_item_stack_density(item_name, item_type) 135 | -- This depends on two things - the stack size startup setting (defaulting to 5) 136 | -- as well as the stack size of the item 137 | -- For instance if a mod adds an item whose stacks only go to 5 but the startup setting 138 | -- is for items to stack to 10, most items will be stacking to 10 but that specific item will only stack to 5 139 | local stack_size = DBL.STACK_SIZE 140 | if data.raw[item_type] and data.raw[item_type][item_name] then 141 | if data.raw[item_type][item_name].stack_size < stack_size then 142 | stack_size = data.raw[item_type][item_name].stack_size 143 | end 144 | end 145 | return stack_size 146 | end 147 | 148 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 149 | 150 | local allowed_item_types = { 151 | ["item"] = true, 152 | ["ammo"] = true, 153 | ["gun"] = true, 154 | ["tool"] = true, 155 | ["repair-tool"] = true, 156 | ["module"] = true, 157 | ["item-with-label"] = true, 158 | ["item-with-tags"] = true, 159 | ["capsule"] = true, 160 | ["rail-planner"] = true 161 | } 162 | 163 | function deadlock.add_stack(item_name, graphic_path, target_tech, icon_size, item_type, mipmap_levels) 164 | -- item_name -- required, item to stack 165 | -- graphic_path -- recommended, path to icon to use for dynamic icon generation 166 | -- target_tech -- optional, the tech to unlock this stacking recipe with, often deadlock-stacking-[1-3] (if not provided, you must unlock in a tech in your own mod) 167 | -- icon_size -- optional, defaults to 64 168 | -- item_type -- optional, defaults to "item" 169 | -- mipmap_levels -- optional, defaults to nil, only ever used if graphic_path is also provided 170 | 171 | ---- validation ---- 172 | DBL.debug("Beginning data validation for new stacked item") 173 | if not item_type then 174 | item_type = "item" 175 | end 176 | if not allowed_item_types[item_type] then 177 | DBL.log_error(string.format("Item type not allowed for %s", item_name)) 178 | return 179 | end 180 | if not data.raw[item_type][item_name] then 181 | DBL.log_error(string.format("Can't create stacks for item that doesn't exist %s", item_name)) 182 | return 183 | end 184 | if icon_size and (icon_size ~= 32 and icon_size ~= 64 and icon_size ~= 128) then 185 | DBL.log_error(string.format("Invalid icon_size for %s", item_name)) 186 | return 187 | end 188 | if not icon_size then 189 | icon_size = 64 190 | end 191 | DBL.debug(string.format("Data validation completed for stacked item %s", item_name)) 192 | if settings.startup["deadlock-enable-beltboxes"].value then 193 | local stack_size = deadlock.get_item_stack_density(item_name, item_type) 194 | DBL.create_stacked_item(item_name, item_type, graphic_path, icon_size, stack_size, mipmap_levels) 195 | DBL.create_stacking_recipes(item_name, item_type, stack_size) 196 | if target_tech then 197 | DBL.add_stacks_to_tech(item_name, target_tech) 198 | end 199 | end 200 | end 201 | 202 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 203 | 204 | function deadlock.deferred_stacked_item_updates() 205 | DBL.deferred_stacked_item_updates() 206 | end 207 | 208 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 209 | 210 | local function product_prototype_uses_item(proto, item) 211 | for _,p in pairs(proto) do 212 | if p.name and p.name == item then return true 213 | elseif p[1] == item then return true end 214 | end 215 | return false 216 | end 217 | 218 | local function uses_item_as_ingredient(recipe, item) 219 | if recipe.ingredients and product_prototype_uses_item(recipe.ingredients, item) then return true end 220 | if recipe.normal and recipe.normal.ingredients and product_prototype_uses_item(recipe.normal.ingredients, item) then return true end 221 | if recipe.expensive and recipe.expensive.ingredients and product_prototype_uses_item(recipe.expensive.ingredients, item) then return true end 222 | return false 223 | end 224 | 225 | local function uses_item_as_result(recipe, item) 226 | if recipe.result == item then return true end 227 | if recipe.normal and recipe.normal.result == item then return true end 228 | if recipe.expensive and recipe.expensive.result == item then return true end 229 | if recipe.results and product_prototype_uses_item(recipe.results, item) then return true end 230 | if recipe.normal and recipe.normal.results and product_prototype_uses_item(recipe.normal.results, item) then return true end 231 | if recipe.expensive and recipe.expensive.results and product_prototype_uses_item(recipe.expensive.results, item) then return true end 232 | return false 233 | end 234 | 235 | local function is_value_in_table(t, value) 236 | if not t or not value then return false end 237 | for k,v in pairs(t) do 238 | if value == v then return true end 239 | end 240 | return false 241 | end 242 | 243 | -- destroy_stack() - removes a stacked item and any recipe/tech references to it 244 | -- item_name -- required, the base item name 245 | function deadlock.destroy_stack(base_item_name) 246 | local item_name = "deadlock-stack-"..base_item_name 247 | local stack_recipe_name = "deadlock-stacks-stack-"..base_item_name 248 | local unstack_recipe_name = "deadlock-stacks-unstack-"..base_item_name 249 | local item_name = "deadlock-stack-"..base_item_name 250 | -- remove the item 251 | if data.raw.item[item_name] then 252 | DBL.debug("Removed item "..item_name) 253 | data.raw.item[item_name] = nil 254 | end 255 | -- remove all recipes that use stacks as either ingredient or result 256 | -- we don't only target stack and unstack recipes because other mods may have used stacks as ingredients by now 257 | -- keep a list of which recipes got removed, so we can search tech unlocks 258 | local dead_recipes = {} 259 | for _,recipe in pairs(data.raw.recipe) do 260 | if uses_item_as_ingredient(recipe, item_name) or uses_item_as_result(recipe, item_name) then 261 | DBL.debug("Removed recipe "..recipe.name) 262 | data.raw.recipe[recipe.name] = nil 263 | table.insert(dead_recipes, recipe.name) 264 | end 265 | end 266 | -- remove all the removed recipe tech unlocks 267 | for _,tech in pairs(data.raw.technology) do 268 | if tech.effects then 269 | local temp = {} 270 | local found = false 271 | for _,effect in pairs(tech.effects) do 272 | if effect.type ~= "unlock-recipe" or not is_value_in_table(dead_recipes, effect.recipe) then 273 | table.insert(temp,effect) 274 | else found = true end 275 | end 276 | if found then DBL.debug("Removed unlocks from "..tech.name) end 277 | tech.effects = table.deepcopy(temp) 278 | end 279 | end 280 | -- remove item order 281 | DBL.item_order[base_item_name] = nil 282 | DBL.recipe_order[base_item_name] = nil 283 | end 284 | 285 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 286 | 287 | -- deadlock.destroy_vanilla_stacks() 288 | -- This is the same as calling destroy_crate() on every vanilla item the mod creates by default 289 | function deadlock.destroy_vanilla_stacks() 290 | for tier,items in ipairs(DBL.VANILLA_ITEMS) do 291 | for _,item in pairs(items) do 292 | deadlock.destroy_stack(item) 293 | end 294 | end 295 | end 296 | 297 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 298 | 299 | -- tables for legacy interfaces from early 0.16 versions 300 | deadlock_loaders = {} 301 | deadlock_stacking = {} 302 | 303 | ------------------------------------------------------------------------------------------------------------------------------------------------------ 304 | 305 | function deadlock_loaders.create(tier_table) 306 | DBL.log_warning("deadlock_loaders.create() - this function is deprecated, consider using deadlock.add_tier() instead") 307 | if not tier_table then 308 | DBL.log_error("Nothing passed, a table is required") 309 | return 310 | end 311 | if type(tier_table) ~= "table" then 312 | DBL.log_error("Non-table passed, a table is required") 313 | return 314 | end 315 | -- translate the legacy table to one that the add_tier function accepts and matching entity names that the old version created 316 | tier_table.loader = string.format("deadlock-loader-%d", tier_table.tier) 317 | tier_table.loader_ingredients = tier_table.ingredients 318 | tier_table.ingredients = nil 319 | tier_table.loader_recipe = string.format("deadlock-loader-%d", tier_table.tier) 320 | tier_table.loader_item = string.format("deadlock-loader-%d", tier_table.tier) 321 | tier_table.loader_category = tier_table.crafting_category 322 | tier_table.crafting_category = nil 323 | tier_table.beltbox = string.format("deadlock-beltbox-entity-%d", tier_table.tier) 324 | tier_table.beltbox_recipe = string.format("deadlock-beltbox-recipe-%d", tier_table.tier) 325 | tier_table.beltbox_item = string.format("deadlock-beltbox-item-%d", tier_table.tier) 326 | tier_table.beltbox_technology = string.format("deadlock-stacking-%d", tier_table.tier) 327 | 328 | DBL.debug(string.format("Calling add_tier for legacy tier %d", tier_table.tier)) 329 | deadlock.add_tier(tier_table) 330 | end 331 | 332 | function deadlock_stacking.create(item_name, graphic_path, target_tech, icon_size) 333 | DBL.log_warning("deadlock_stacking.create() - this function is deprecated, consider using deadlock.add_stack() instead") 334 | deadlock.add_stack(item_name, graphic_path, target_tech, icon_size) 335 | end 336 | 337 | function deadlock_stacking.create_stack(item_name, graphic_path, target_tech, icon_size) 338 | DBL.log_warning("deadlock_stacking.create_stack() - this function is deprecated, consider using deadlock.add_stack() instead") 339 | deadlock.add_stack(item_name, graphic_path, target_tech, icon_size) 340 | end 341 | 342 | function deadlock_stacking.reset() 343 | DBL.log_warning("deadlock_stacking.reset() - this function is deprecated, consider using deadlock.destroy_vanilla_stacks() instead") 344 | for tech_name, technology in pairs(DBL.BELTBOX_TECHS) do 345 | -- iterate in reverse, clear all stack items but leave beltboxes 346 | for i = #technology.effects, 1, -1 do 347 | if technology.effects[i].type == "unlock-recipe" and string.find(technology.effects[i].recipe, "deadlock%-stacks%-") then 348 | table.remove(technology.effects, i) 349 | end 350 | end 351 | end 352 | DBL.debug("Technologies cleared.") 353 | end 354 | 355 | function deadlock_stacking.remove(target_tech) 356 | DBL.log_warning("deadlock_stacking.remove() - this function is deprecated, consider using deadlock.destroy_stack() instead") 357 | for tech_name, technology in pairs(DBL.BELTBOX_TECHS) do 358 | -- iterate in reverse, clear all matching items 359 | for i = #technology.effects, 1, -1 do 360 | if technology.effects[i].type == "unlock-recipe" and string.find(technology.effects[i].recipe, target_tech, 1, true) then 361 | DBL.debug(string.format("Removing recipe %s from technology %s", technology.effects[i].recipe, tech_name)) 362 | table.remove(technology.effects, i) 363 | end 364 | end 365 | end 366 | end 367 | -------------------------------------------------------------------------------- /prototypes/shared.lua: -------------------------------------------------------------------------------- 1 | -- internal module table 2 | local DBL = {} 3 | 4 | function DBL.debug(message) 5 | ---- DEBUG LOGGING ---- 6 | -- set below false to true for debug logging during the data phase to factorio's log file 7 | if false then 8 | log(string.format("DBL: %s", message)) 9 | end 10 | end 11 | 12 | function DBL.log_error(message) 13 | log(string.format("DBL: Error: %s", message)) 14 | end 15 | 16 | function DBL.log_warning(message) 17 | log(string.format("DBL: Warning: %s", message)) 18 | end 19 | 20 | DBL.STACK_SIZE = settings.startup["deadlock-stack-size"].value 21 | DBL.CRAFT_TIME = DBL.STACK_SIZE / 15 22 | 23 | DBL.VANILLA_ITEMS = { 24 | [1] = { "wood", "iron-ore", "copper-ore", "stone", "coal", "iron-plate", "copper-plate", "steel-plate", "stone-brick", "tungsten-ore" }, 25 | [2] = { "copper-cable", "iron-gear-wheel", "iron-stick", "sulfur", "plastic-bar", "solid-fuel", "electronic-circuit", "advanced-circuit" }, 26 | [3] = { "processing-unit", "battery", "uranium-ore", "uranium-235", "uranium-238" }, 27 | } 28 | DBL.VANILLA_ICON_SIZE = 32 29 | 30 | if settings.startup["deadlock-stacking-batch-stacking"].value then 31 | DBL.RECIPE_MULTIPLIER = 4 32 | else 33 | DBL.RECIPE_MULTIPLIER = 1 34 | end 35 | DBL.BELT_COMPONENTS = { 36 | "animations", 37 | "belt_horizontal", 38 | "belt_vertical", 39 | "ending_top", 40 | "ending_bottom", 41 | "ending_side", 42 | "starting_top", 43 | "starting_bottom", 44 | "starting_side", 45 | } 46 | DBL.BELTBOX_TECHS = {} 47 | 48 | if not data.raw["item-subgroup"]["beltboxes"] then 49 | data:extend({ 50 | { 51 | type = "item-subgroup", 52 | name = "loaders", 53 | group = "logistics", 54 | order = "bb", 55 | }, 56 | { 57 | type = "item-subgroup", 58 | name = "beltboxes", 59 | group = "logistics", 60 | order = "bba", 61 | }, 62 | { 63 | type = "recipe-category", 64 | name = "stacking", 65 | }, 66 | { 67 | type = "recipe-category", 68 | name = "unstacking", 69 | }, 70 | }) 71 | end 72 | 73 | -- make a subgroup at the bottom of each crafting tab 74 | for _, group in pairs(data.raw["item-group"]) do 75 | data:extend({ 76 | { 77 | type = "item-subgroup", 78 | name = string.format("stacks-%s", group.name), 79 | group = group.name, 80 | order = "zzzzz", 81 | }, 82 | }) 83 | end 84 | 85 | -- meta-tables for item/recipe order 86 | -- assign a order for the stacked items based on the order in which they're created, 87 | -- remembering the assigned order for any items that get stacking applied multiple times 88 | DBL.item_order = {} 89 | do 90 | -- when this table is checked (during stack creation), the first check for an item in the table will fail 91 | -- and the __index function will be called, assigning an order, storing and returning it 92 | -- for later checks of the same key (item name), the stored order string will be in the table and __index won't be hit. 93 | local item_increment = 1 94 | local item_order_metatable = { 95 | __index = function(table, key) 96 | table[key] = string.format("%03d", item_increment) 97 | item_increment = item_increment + 1 98 | return table[key] 99 | end 100 | } 101 | DBL.item_order = setmetatable(DBL.item_order, item_order_metatable) 102 | end 103 | DBL.recipe_order = {} 104 | do 105 | local recipe_increment = 1 106 | local recipe_order_metatable = { 107 | __index = function(table, key) 108 | table[key] = string.format("%03d", recipe_increment) 109 | recipe_increment = recipe_increment + 1 110 | return table[key] 111 | end 112 | } 113 | DBL.recipe_order = setmetatable(DBL.recipe_order, recipe_order_metatable) 114 | end 115 | 116 | return DBL 117 | -------------------------------------------------------------------------------- /prototypes/vanilla_stacks.lua: -------------------------------------------------------------------------------- 1 | -- stack vanilla items 2 | 3 | local DBL = require("prototypes.shared") 4 | 5 | for tier,items in ipairs(DBL.VANILLA_ITEMS) do 6 | for _,item in pairs(items) do 7 | deadlock.add_stack(item, string.format("__deadlock-beltboxes-loaders__/graphics/icons/square/stacked-%s.png", item), string.format("deadlock-stacking-%d", tier), DBL.VANILLA_ICON_SIZE) 8 | end 9 | end -------------------------------------------------------------------------------- /prototypes/vanilla_tiers.lua: -------------------------------------------------------------------------------- 1 | -- tier 1 2 | deadlock.add_tier({ 3 | transport_belt = "transport-belt", 4 | colour = {r=210, g=180, b=80}, 5 | underground_belt = "underground-belt", 6 | splitter = "splitter", 7 | technology = "logistics", 8 | order = "a", 9 | loader_ingredients = { 10 | {name = "transport-belt", type = "item", amount = 1}, 11 | {name = "iron-plate", type = "item", amount = 5}, 12 | }, 13 | beltbox_ingredients = { 14 | {name = "transport-belt", type = "item", amount = 4}, 15 | {name = "iron-plate", type = "item", amount = 10}, 16 | {name = "iron-gear-wheel", type = "item", amount = 10}, 17 | {name = "electronic-circuit", type = "item", amount = 4}, 18 | }, 19 | beltbox_technology = "deadlock-stacking-1", 20 | }) 21 | if data.raw["loader-1x1"]["transport-belt-loader"] then 22 | data.raw["loader-1x1"]["transport-belt-loader"].next_upgrade = "fast-transport-belt-loader" 23 | end 24 | if data.raw.furnace["transport-belt-beltbox"] then 25 | data.raw.furnace["transport-belt-beltbox"].next_upgrade = "fast-transport-belt-beltbox" 26 | end 27 | 28 | -- tier 2 29 | deadlock.add_tier({ 30 | transport_belt = "fast-transport-belt", 31 | colour = {r=210, g=60, b=60}, 32 | underground_belt = "fast-underground-belt", 33 | splitter = "fast-splitter", 34 | technology = "logistics-2", 35 | order = "b", 36 | loader_ingredients = { 37 | {name = "transport-belt-loader", type = "item", amount = 1}, 38 | {name = "iron-gear-wheel", type = "item", amount = 20}, 39 | }, 40 | beltbox_ingredients = { 41 | {name = "transport-belt-beltbox", type = "item", amount = 1}, 42 | {name = "iron-plate", type = "item", amount = 20}, 43 | {name = "iron-gear-wheel", type = "item", amount = 20}, 44 | {name = "advanced-circuit", type = "item", amount = 2}, 45 | }, 46 | beltbox_technology = "deadlock-stacking-2", 47 | }) 48 | if data.raw.technology["deadlock-stacking-2"] then 49 | table.insert(data.raw.technology["deadlock-stacking-2"].prerequisites, "deadlock-stacking-1") 50 | end 51 | if data.raw["loader-1x1"]["fast-transport-belt-loader"] then 52 | data.raw["loader-1x1"]["fast-transport-belt-loader"].next_upgrade = "express-transport-belt-loader" 53 | end 54 | if data.raw.furnace["fast-transport-belt-beltbox"] then 55 | data.raw.furnace["fast-transport-belt-beltbox"].next_upgrade = "express-transport-belt-beltbox" 56 | end 57 | 58 | -- vary which category t3 is used for depending on whether space age is present 59 | local t3_category 60 | if mods["space-age"] then 61 | t3_category = "crafting-with-fluid-or-metallurgy" 62 | else 63 | t3_category = "crafting-with-fluid" 64 | end 65 | 66 | -- tier 3 67 | deadlock.add_tier({ 68 | transport_belt = "express-transport-belt", 69 | colour = {r=80, g=180, b=210}, 70 | underground_belt = "express-underground-belt", 71 | splitter = "express-splitter", 72 | technology = "logistics-3", 73 | order = "c", 74 | loader_ingredients = { 75 | {name = "fast-transport-belt-loader", type = "item", amount = 1}, 76 | {name = "iron-gear-wheel", type = "item", amount = 40}, 77 | {name = "lubricant", type = "fluid", amount = 20}, 78 | }, 79 | loader_category = t3_category, 80 | beltbox_ingredients = { 81 | {name = "fast-transport-belt-beltbox", type = "item", amount = 1}, 82 | {name = "iron-plate", type = "item", amount = 30}, 83 | {name = "iron-gear-wheel", type = "item", amount = 30}, 84 | {name = "lubricant", type = "fluid", amount = 100}, 85 | }, 86 | beltbox_category = t3_category, 87 | beltbox_technology = "deadlock-stacking-3", 88 | }) 89 | if data.raw.technology["deadlock-stacking-3"] then 90 | table.insert(data.raw.technology["deadlock-stacking-3"].prerequisites, "deadlock-stacking-2") 91 | end 92 | 93 | if mods["space-age"] then 94 | -- add the upgrade for t3 only if space age is present and we're gonna be loading t4 95 | if data.raw["loader-1x1"]["express-transport-belt-loader"] then 96 | data.raw["loader-1x1"]["express-transport-belt-loader"].next_upgrade = "turbo-transport-belt-loader" 97 | end 98 | if data.raw.furnace["express-transport-belt-beltbox"] then 99 | data.raw.furnace["express-transport-belt-beltbox"].next_upgrade = "turbo-transport-belt-beltbox" 100 | end 101 | 102 | -- tier 4 103 | deadlock.add_tier({ 104 | transport_belt = "turbo-transport-belt", 105 | colour = {r=160, g=190, b=80}, 106 | underground_belt = "turbo-underground-belt", 107 | splitter = "turbo-splitter", 108 | technology = "turbo-transport-belt", 109 | order = "d", 110 | loader_ingredients = { 111 | {name = "express-transport-belt-loader", type = "item", amount = 1}, 112 | {name = "tungsten-plate", type = "item", amount = 20}, 113 | {name = "lubricant", type = "fluid", amount = 20}, 114 | }, 115 | loader_category = "crafting-with-fluid-or-metallurgy", 116 | beltbox_ingredients = { 117 | {name = "express-transport-belt-beltbox", type = "item", amount = 1}, 118 | {name = "tungsten-plate", type = "item", amount = 15}, 119 | {name = "iron-gear-wheel", type = "item", amount = 15}, 120 | {name = "lubricant", type = "fluid", amount = 100}, 121 | }, 122 | beltbox_category = "crafting-with-fluid-or-metallurgy", 123 | beltbox_technology = "deadlock-stacking-4", 124 | }) 125 | if data.raw.technology["deadlock-stacking-4"] then 126 | table.insert(data.raw.technology["deadlock-stacking-4"].prerequisites, "deadlock-stacking-3") 127 | end 128 | end 129 | -------------------------------------------------------------------------------- /settings.lua: -------------------------------------------------------------------------------- 1 | data:extend({ 2 | -- startup 3 | { 4 | type = "bool-setting", 5 | name = "deadlock-enable-beltboxes", 6 | order = "a", 7 | setting_type = "startup", 8 | default_value = true, 9 | }, 10 | { 11 | type = "bool-setting", 12 | name = "deadlock-enable-loaders", 13 | order = "b", 14 | setting_type = "startup", 15 | default_value = true, 16 | }, 17 | { 18 | type = "int-setting", 19 | name = "deadlock-stack-size", 20 | order = "bb", 21 | setting_type = "startup", 22 | default_value = 5, 23 | allowed_values = { 24 | 4, 25 | 5, 26 | 8, 27 | 10, 28 | 16, 29 | 25, 30 | 32, 31 | 50, 32 | 64, 33 | 100, 34 | 128, 35 | }, 36 | }, 37 | { 38 | type = "bool-setting", 39 | name = "deadlock-stacking-auto-unstack", 40 | order = "c", 41 | setting_type = "startup", 42 | default_value = false, 43 | }, 44 | { 45 | type = "bool-setting", 46 | name = "deadlock-stacking-hide-unstacking", 47 | order = "d", 48 | setting_type = "startup", 49 | default_value = false, 50 | }, 51 | { 52 | type = "bool-setting", 53 | name = "deadlock-stacking-batch-stacking", 54 | order = "e", 55 | setting_type = "startup", 56 | default_value = false, 57 | }, 58 | { 59 | type = "bool-setting", 60 | name = "deadlock-stacking-show-alt-info", 61 | order = "f", 62 | setting_type = "startup", 63 | default_value = true, 64 | }, 65 | { 66 | type = "bool-setting", 67 | name = "deadlock-strict-fast-replace-beltboxes", 68 | order = "f", 69 | setting_type = "startup", 70 | default_value = false, 71 | }, 72 | { 73 | type = "bool-setting", 74 | name = "deadlock-strict-fast-replace-loaders", 75 | order = "g", 76 | setting_type = "startup", 77 | default_value = false, 78 | }, 79 | -- runtime 80 | { 81 | type = "bool-setting", 82 | name = "deadlock-loaders-snap-to-belts", 83 | order = "a", 84 | setting_type = "runtime-per-user", 85 | default_value = true, 86 | }, 87 | { 88 | type = "bool-setting", 89 | name = "deadlock-loaders-snap-to-inventories", 90 | order = "b", 91 | setting_type = "runtime-per-user", 92 | default_value = false, 93 | }, 94 | }) 95 | -------------------------------------------------------------------------------- /sounds/fan.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/sounds/fan.ogg -------------------------------------------------------------------------------- /thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shanemadden/factorio-deadlock-beltboxes-loaders/5a824b7ee71c3bd9012acff44874ec2a2545a2ad/thumbnail.png --------------------------------------------------------------------------------