Distribution modes for tunnels

- Item distribution across belts using brass tunnels can now be configured with a wrench
- Added new icons for the distribution options of arms and tunnels
- Removed obsolete code
- Fixed some weirdness with creative crates and funnels
This commit is contained in:
simibubi 2020-09-13 22:00:11 +02:00
parent 651e06a70a
commit 03cf441674
22 changed files with 398 additions and 205 deletions

View file

@ -350,16 +350,16 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j
7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
c87674f2935327f78657f1bb44b3b10b6697a548 assets/create/lang/en_ud.json c87674f2935327f78657f1bb44b3b10b6697a548 assets/create/lang/en_ud.json
ec8fc3f55847ad667752fdc06fc8b5de75253cf4 assets/create/lang/en_us.json 0e38385f3de32bfc0f5d3d90dfa635469e953e43 assets/create/lang/en_us.json
bab998d2bbb0e24147e8dd34006bf94a4ad857e7 assets/create/lang/unfinished/de_de.json cb59266eb110493f41cd8754915e2c2626063742 assets/create/lang/unfinished/de_de.json
e3e51ea8e3e540a4f363610195050b0bbe8b452d assets/create/lang/unfinished/fr_fr.json 9f1f8ebf3683613729f0c4d62d12d3146cfdb634 assets/create/lang/unfinished/fr_fr.json
b2bc925b69b276f03dbb30aa996e3b8677c9eb16 assets/create/lang/unfinished/it_it.json a6d24acb90e85ed13a5bd36a4e95750319a01de5 assets/create/lang/unfinished/it_it.json
272aa6f6567b451a5204283f580f642990c04ce0 assets/create/lang/unfinished/ja_jp.json 5dbd2b38becc4e985cc926bab5c58e8c7dfaf7e7 assets/create/lang/unfinished/ja_jp.json
1e3115cbbdcb55dfa871ae31fc88cea78544fc5a assets/create/lang/unfinished/ko_kr.json 4065e282b5860497090e86b3bdf2773f9888f502 assets/create/lang/unfinished/ko_kr.json
e470b095bfc10d3fa7141a4d8860eaf093be9e62 assets/create/lang/unfinished/nl_nl.json e1baa1589c53467ca2f610c3f0cc51c861afdcff assets/create/lang/unfinished/nl_nl.json
1c3f2f8cf9d7d5280d7495da3b8c89481fd5dcee assets/create/lang/unfinished/pt_br.json 8590ef541ece9eae76135b3e93c53798b3d37aac assets/create/lang/unfinished/pt_br.json
a49430d7b66c52cde1880ccb7fd6123fb5ab2b2b assets/create/lang/unfinished/ru_ru.json 7b67a7b85631c83f6803eb717bced55d0efb76b7 assets/create/lang/unfinished/ru_ru.json
5d569d86a3d8af114bb6b99a6410c3823d2191f8 assets/create/lang/unfinished/zh_cn.json 29a47e6bc1f85467af17f97d30e2e0100bea99ea assets/create/lang/unfinished/zh_cn.json
846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json
1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json
1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json

View file

@ -836,10 +836,18 @@
"create.tooltip.generationSpeed": "Generates at %1$s %2$s", "create.tooltip.generationSpeed": "Generates at %1$s %2$s",
"create.tooltip.analogStrength": "Analog Strength: %1$s/15", "create.tooltip.analogStrength": "Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "Selection Mode", "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "Prefer First Target",
"create.tunnel.selection_mode.split": "Split",
"create.tunnel.selection_mode.forced_split": "Forced Split",
"create.tunnel.selection_mode.round_robin": "Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "Prefer Nearest",
"create.tunnel.selection_mode.randomize": "Randomize",
"create.gui.config.overlay1": "Hi :)", "create.gui.config.overlay1": "Hi :)",
"create.gui.config.overlay2": "This is a sample overlay", "create.gui.config.overlay2": "This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 794", "_": "Missing Localizations: 800",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 418", "_": "Missing Localizations: 424",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "Génère à %1$s %2$s", "create.tooltip.generationSpeed": "Génère à %1$s %2$s",
"create.tooltip.analogStrength": "Force analogique: %1$s/15", "create.tooltip.analogStrength": "Force analogique: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 402", "_": "Missing Localizations: 408",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "Genera %1$s %2$s", "create.tooltip.generationSpeed": "Genera %1$s %2$s",
"create.tooltip.analogStrength": "Forza Analogica: %1$s/15", "create.tooltip.analogStrength": "Forza Analogica: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 397", "_": "Missing Localizations: 403",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "%1$s %2$sを生成", "create.tooltip.generationSpeed": "%1$s %2$sを生成",
"create.tooltip.analogStrength": "アナログ強度: %1$s/15", "create.tooltip.analogStrength": "アナログ強度: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 402", "_": "Missing Localizations: 408",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "%1$s %2$s만큼 발전함", "create.tooltip.generationSpeed": "%1$s %2$s만큼 발전함",
"create.tooltip.analogStrength": "레드스톤 출력: %1$s/15", "create.tooltip.analogStrength": "레드스톤 출력: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 732", "_": "Missing Localizations: 738",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 801", "_": "Missing Localizations: 807",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 795", "_": "Missing Localizations: 801",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -1,5 +1,5 @@
{ {
"_": "Missing Localizations: 82", "_": "Missing Localizations: 88",
"_": "->------------------------] Game Elements [------------------------<-", "_": "->------------------------] Game Elements [------------------------<-",
@ -837,10 +837,18 @@
"create.tooltip.generationSpeed": "产生 %1$s %2$s", "create.tooltip.generationSpeed": "产生 %1$s %2$s",
"create.tooltip.analogStrength": "调节强度: %1$s/15", "create.tooltip.analogStrength": "调节强度: %1$s/15",
"create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "UNLOCALIZED: First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "UNLOCALIZED: Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "UNLOCALIZED: Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "UNLOCALIZED: Prefer First Target",
"create.tunnel.selection_mode.split": "UNLOCALIZED: Split",
"create.tunnel.selection_mode.forced_split": "UNLOCALIZED: Forced Split",
"create.tunnel.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "UNLOCALIZED: Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "UNLOCALIZED: Prefer Nearest",
"create.tunnel.selection_mode.randomize": "UNLOCALIZED: Randomize",
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)", "create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay", "create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",

View file

@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock; import com.simibubi.create.content.logistics.block.inventories.AdjustableCrateBlock;
import com.simibubi.create.content.logistics.block.inventories.CreativeCrateInventory;
import net.minecraft.block.ChestBlock; import net.minecraft.block.ChestBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
@ -86,17 +85,14 @@ public class MountedStorage {
public MountedStorage(CompoundNBT nbt) { public MountedStorage(CompoundNBT nbt) {
handler = new ItemStackHandler(); handler = new ItemStackHandler();
working = nbt != null; working = nbt != null;
if (working) { if (working)
if (nbt.contains("isCreativeCrate") && nbt.getBoolean("isCreativeCrate"))
handler = new CreativeCrateInventory();
handler.deserializeNBT(nbt); handler.deserializeNBT(nbt);
}
} }
public void fill(TileEntity te) { public void fill(TileEntity te) {
IItemHandler teHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) IItemHandler teHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
.orElse(dummyHandler); .orElse(dummyHandler);
if (teHandler != dummyHandler && teHandler instanceof IItemHandlerModifiable && !(teHandler instanceof CreativeCrateInventory)) { if (teHandler != dummyHandler && teHandler instanceof IItemHandlerModifiable) {
IItemHandlerModifiable inv = (IItemHandlerModifiable) teHandler; IItemHandlerModifiable inv = (IItemHandlerModifiable) teHandler;
for (int slot = 0; slot < Math.min(inv.getSlots(), handler.getSlots()); slot++) for (int slot = 0; slot < Math.min(inv.getSlots(), handler.getSlots()); slot++)
inv.setStackInSlot(slot, handler.getStackInSlot(slot)); inv.setStackInSlot(slot, handler.getStackInSlot(slot));
@ -120,8 +116,6 @@ public class MountedStorage {
return false; return false;
if (AllTileEntities.ADJUSTABLE_CRATE.is(te)) if (AllTileEntities.ADJUSTABLE_CRATE.is(te))
return true; return true;
if (AllTileEntities.CREATIVE_CRATE.is(te))
return true;
if (te instanceof ShulkerBoxTileEntity) if (te instanceof ShulkerBoxTileEntity)
return true; return true;
if (te instanceof ChestTileEntity) if (te instanceof ChestTileEntity)

View file

@ -80,7 +80,8 @@ public class BeltTileEntity extends KineticTileEntity {
@Override @Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) { public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours); super.addBehaviours(behaviours);
behaviours.add(new DirectBeltInputBehaviour(this).setInsertionHandler(this::tryInsertingFromSide)); behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::canInsertFrom)
.setInsertionHandler(this::tryInsertingFromSide));
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems) behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
.withStackPlacement(this::getWorldPositionOf)); .withStackPlacement(this::getWorldPositionOf));
} }
@ -383,12 +384,10 @@ public class BeltTileEntity extends KineticTileEntity {
sendData(); sendData();
} }
/** private boolean canInsertFrom(Direction side) {
* always target a DirectBeltInsertionBehaviour if (getSpeed() == 0)
*/ return false;
@Deprecated return getMovementFacing() != side.getOpposite();
public boolean tryInsertingFromSide(Direction side, ItemStack stack, boolean simulate) {
return tryInsertingFromSide(new TransportedItemStack(stack), side, simulate).isEmpty();
} }
private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) { private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) {

View file

@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -11,11 +12,16 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper; import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.content.contraptions.relays.belt.BeltTileEntity;
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock; import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.CenteredSideValueBoxTransform;
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.SidedFilteringBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.filtering.SidedFilteringBehaviour;
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.INamedIconOptions;
import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollOptionBehaviour;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -36,6 +42,7 @@ import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
import net.minecraftforge.items.ItemHandlerHelper;
public class BrassTunnelTileEntity extends BeltTunnelTileEntity { public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
@ -49,7 +56,9 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
List<Pair<BlockPos, Direction>> distributionTargets; List<Pair<BlockPos, Direction>> distributionTargets;
int distributionDistanceLeft; int distributionDistanceLeft;
int distributionDistanceRight; int distributionDistanceRight;
int previousOutputIndex;
protected ScrollOptionBehaviour<SelectionMode> selectionMode;
private LazyOptional<IItemHandler> beltCapability; private LazyOptional<IItemHandler> beltCapability;
private LazyOptional<IItemHandler> tunnelCapability; private LazyOptional<IItemHandler> tunnelCapability;
@ -59,6 +68,27 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
stackToDistribute = ItemStack.EMPTY; stackToDistribute = ItemStack.EMPTY;
beltCapability = LazyOptional.empty(); beltCapability = LazyOptional.empty();
tunnelCapability = LazyOptional.of(() -> new BrassTunnelItemHandler(this)); tunnelCapability = LazyOptional.of(() -> new BrassTunnelItemHandler(this));
previousOutputIndex = 0;
}
@Override
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours);
behaviours.add(selectionMode = new ScrollOptionBehaviour<>(SelectionMode.class,
Lang.translate("logistics.when_multiple_outputs_available"), this,
new CenteredSideValueBoxTransform((state, d) -> d == Direction.UP)));
selectionMode.requiresWrench();
// Propagate settings across connected tunnels
selectionMode.withCallback(setting -> {
for (boolean side : Iterate.trueAndFalse) {
if (!isConnected(side))
continue;
BrassTunnelTileEntity adjacent = getAdjacent(side);
if (adjacent != null)
adjacent.selectionMode.setValue(setting);
}
});
} }
@Override @Override
@ -66,6 +96,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
super.tick(); super.tick();
BeltTileEntity beltBelow = BeltHelper.getSegmentTE(world, pos.down()); BeltTileEntity beltBelow = BeltHelper.getSegmentTE(world, pos.down());
if (distributionProgress > 0)
distributionProgress--;
if (beltBelow == null || beltBelow.getSpeed() == 0) if (beltBelow == null || beltBelow.getSpeed() == 0)
return; return;
if (stackToDistribute.isEmpty()) if (stackToDistribute.isEmpty())
@ -80,7 +112,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
for (Pair<BrassTunnelTileEntity, Direction> pair : gatherValidOutputs()) { for (Pair<BrassTunnelTileEntity, Direction> pair : gatherValidOutputs()) {
BrassTunnelTileEntity tunnel = pair.getKey(); BrassTunnelTileEntity tunnel = pair.getKey();
Direction output = pair.getValue(); Direction output = pair.getValue();
if (!insertIntoTunnel(tunnel, output, stackToDistribute, true).isEmpty()) if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null)
continue; continue;
distributionTargets.add(Pair.of(tunnel.pos, output)); distributionTargets.add(Pair.of(tunnel.pos, output));
int distance = tunnel.pos.getX() + tunnel.pos.getZ() - pos.getX() - pos.getZ(); int distance = tunnel.pos.getX() + tunnel.pos.getZ() - pos.getX() - pos.getZ();
@ -93,12 +125,11 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
if (distributionTargets.isEmpty()) if (distributionTargets.isEmpty())
return; return;
distributionProgress = 0; distributionProgress = 10;
sendData(); sendData();
return; return;
} }
// TODO this is instant for now
if (distributionProgress == 0) { if (distributionProgress == 0) {
List<Pair<BrassTunnelTileEntity, Direction>> validTargets = new ArrayList<>(); List<Pair<BrassTunnelTileEntity, Direction>> validTargets = new ArrayList<>();
for (Pair<BlockPos, Direction> pair : distributionTargets) { for (Pair<BlockPos, Direction> pair : distributionTargets) {
@ -110,36 +141,73 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
validTargets.add(Pair.of((BrassTunnelTileEntity) te, output)); validTargets.add(Pair.of((BrassTunnelTileEntity) te, output));
} }
if (validTargets.size() == 0) { distribute(validTargets);
distributionProgress = -1;
sendData();
return;
}
int stackSizeBefore = stackToDistribute.getCount();
int stackSizeForOutput = stackSizeBefore / validTargets.size();
int remainder = stackSizeBefore % validTargets.size();
for (Pair<BrassTunnelTileEntity, Direction> pair : validTargets) {
BrassTunnelTileEntity tunnel = pair.getKey();
Direction side = pair.getValue();
int stackSize = stackSizeForOutput + (remainder > 0 ? 1 : 0);
ItemStack toOutput = stackToDistribute.copy()
.split(stackSize);
if (!insertIntoTunnel(tunnel, side, toOutput, false).isEmpty())
continue;
stackToDistribute.shrink(stackSize);
remainder--;
}
distributionProgress = -1; distributionProgress = -1;
markDirty();
sendData();
return; return;
} }
} }
private static Random rand = new Random();
private void distribute(List<Pair<BrassTunnelTileEntity, Direction>> validTargets) {
final int amountTargets = validTargets.size();
if (amountTargets == 0)
return;
int indexStart = previousOutputIndex % amountTargets;
SelectionMode mode = selectionMode.get();
boolean force = mode == SelectionMode.FORCED_ROUND_ROBIN || mode == SelectionMode.FORCED_SPLIT;
boolean split = mode == SelectionMode.FORCED_SPLIT || mode == SelectionMode.SPLIT;
if (mode == SelectionMode.RANDOMIZE)
indexStart = rand.nextInt(amountTargets);
if (mode == SelectionMode.PREFER_NEAREST)
indexStart = 0;
ItemStack toDistribute = null;
for (boolean simulate : Iterate.trueAndFalse) {
int index = indexStart;
int stackSize = stackToDistribute.getCount();
int splitStackSize = stackSize / amountTargets;
int splitRemainder = stackSize % amountTargets;
int visited = 0;
toDistribute = stackToDistribute.copy();
if (!force && simulate)
continue;
while (visited < amountTargets) {
Pair<BrassTunnelTileEntity, Direction> pair = validTargets.get(index);
BrassTunnelTileEntity tunnel = pair.getKey();
Direction side = pair.getValue();
index = (index + 1) % amountTargets;
visited++;
int count = split ? splitStackSize + (splitRemainder > 0 ? 1 : 0) : stackSize;
ItemStack toOutput = ItemHandlerHelper.copyStackWithSize(toDistribute, count);
ItemStack remainder = insertIntoTunnel(tunnel, side, toOutput, simulate);
if (remainder == null || !remainder.isEmpty()) {
if (force)
return;
continue;
}
toDistribute.shrink(count);
if (toDistribute.isEmpty())
break;
splitRemainder--;
if (!split)
break;
}
}
stackToDistribute = toDistribute.copy();
previousOutputIndex++;
previousOutputIndex %= amountTargets;
notifyUpdate();
}
public void setStackToDistribute(ItemStack stack) { public void setStackToDistribute(ItemStack stack) {
stackToDistribute = stack; stackToDistribute = stack;
distributionProgress = -1; distributionProgress = -1;
@ -151,21 +219,24 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
return stackToDistribute; return stackToDistribute;
} }
@Nullable
protected ItemStack insertIntoTunnel(BrassTunnelTileEntity tunnel, Direction side, ItemStack stack, protected ItemStack insertIntoTunnel(BrassTunnelTileEntity tunnel, Direction side, ItemStack stack,
boolean simulate) { boolean simulate) {
if (stack.isEmpty()) if (stack.isEmpty())
return stack; return stack;
if (!tunnel.testFlapFilter(side, stack)) if (!tunnel.testFlapFilter(side, stack))
return stack; return null;
BeltTileEntity below = BeltHelper.getSegmentTE(world, tunnel.pos.down()); BeltTileEntity below = BeltHelper.getSegmentTE(world, tunnel.pos.down());
if (below == null) if (below == null)
return stack; return null;
BlockPos offset = tunnel.getPos() BlockPos offset = tunnel.getPos()
.down() .down()
.offset(side); .offset(side);
DirectBeltInputBehaviour sideOutput = TileEntityBehaviour.get(world, offset, DirectBeltInputBehaviour.TYPE); DirectBeltInputBehaviour sideOutput = TileEntityBehaviour.get(world, offset, DirectBeltInputBehaviour.TYPE);
if (sideOutput != null) { if (sideOutput != null) {
if (!sideOutput.canInsertFromSide(side))
return null;
ItemStack result = sideOutput.handleInsertion(stack, side, simulate); ItemStack result = sideOutput.handleInsertion(stack, side, simulate);
if (result.isEmpty() && !simulate) if (result.isEmpty() && !simulate)
tunnel.flap(side, true); tunnel.flap(side, true);
@ -177,7 +248,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
if (!Block.hasSolidSide(world.getBlockState(offset), world, offset, side.getOpposite())) { if (!Block.hasSolidSide(world.getBlockState(offset), world, offset, side.getOpposite())) {
BeltTileEntity controllerTE = below.getControllerTE(); BeltTileEntity controllerTE = below.getControllerTE();
if (controllerTE == null) if (controllerTE == null)
return stack; return null;
if (!simulate) { if (!simulate) {
tunnel.flap(side, true); tunnel.flap(side, true);
@ -199,7 +270,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
return ItemStack.EMPTY; return ItemStack.EMPTY;
} }
return stack; return null;
} }
public boolean testFlapFilter(Direction side, ItemStack stack) { public boolean testFlapFilter(Direction side, ItemStack stack) {
@ -334,6 +405,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
compound.put("StackToDistribute", stackToDistribute.serializeNBT()); compound.put("StackToDistribute", stackToDistribute.serializeNBT());
compound.putFloat("DistributionProgress", distributionProgress); compound.putFloat("DistributionProgress", distributionProgress);
compound.putInt("PreviousIndex", previousOutputIndex);
compound.putInt("DistanceLeft", distributionDistanceLeft); compound.putInt("DistanceLeft", distributionDistanceLeft);
compound.putInt("DistanceRight", distributionDistanceRight); compound.putInt("DistanceRight", distributionDistanceRight);
compound.put("Targets", NBTHelper.writeCompoundList(distributionTargets, pair -> { compound.put("Targets", NBTHelper.writeCompoundList(distributionTargets, pair -> {
@ -356,6 +428,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
connectedRight = compound.getBoolean("ConnectedRight"); connectedRight = compound.getBoolean("ConnectedRight");
stackToDistribute = ItemStack.read(compound.getCompound("StackToDistribute")); stackToDistribute = ItemStack.read(compound.getCompound("StackToDistribute"));
distributionProgress = compound.getFloat("DistributionProgress"); distributionProgress = compound.getFloat("DistributionProgress");
previousOutputIndex = compound.getInt("PreviousIndex");
distributionDistanceLeft = compound.getInt("DistanceLeft"); distributionDistanceLeft = compound.getInt("DistanceLeft");
distributionDistanceRight = compound.getInt("DistanceRight"); distributionDistanceRight = compound.getInt("DistanceRight");
distributionTargets = NBTHelper.readCompoundList(compound.getList("Targets", NBT.TAG_COMPOUND), nbt -> { distributionTargets = NBTHelper.readCompoundList(compound.getList("Targets", NBT.TAG_COMPOUND), nbt -> {
@ -391,15 +464,20 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
connectedLeft = nowConnectedLeft; connectedLeft = nowConnectedLeft;
connectivityChanged = true; connectivityChanged = true;
BrassTunnelTileEntity adjacent = getAdjacent(true); BrassTunnelTileEntity adjacent = getAdjacent(true);
if (adjacent != null && !world.isRemote) if (adjacent != null && !world.isRemote) {
adjacent.updateTunnelConnections(); adjacent.updateTunnelConnections();
adjacent.selectionMode.setValue(selectionMode.getValue());
}
} }
if (connectedRight != nowConnectedRight) { if (connectedRight != nowConnectedRight) {
connectedRight = nowConnectedRight; connectedRight = nowConnectedRight;
connectivityChanged = true; connectivityChanged = true;
BrassTunnelTileEntity adjacent = getAdjacent(false); BrassTunnelTileEntity adjacent = getAdjacent(false);
if (adjacent != null && !world.isRemote) if (adjacent != null && !world.isRemote) {
adjacent.updateTunnelConnections(); adjacent.updateTunnelConnections();
adjacent.selectionMode.setValue(selectionMode.getValue());
}
} }
if (filtering != null) if (filtering != null)
@ -435,6 +513,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
if (adjacentBlockState.get(BrassTunnelBlock.HORIZONTAL_AXIS) != axis) if (adjacentBlockState.get(BrassTunnelBlock.HORIZONTAL_AXIS) != axis)
return null; return null;
TileEntity adjacentTE = world.getTileEntity(adjacentPos); TileEntity adjacentTE = world.getTileEntity(adjacentPos);
if (adjacentTE.isRemoved())
return null;
if (!(adjacentTE instanceof BrassTunnelTileEntity)) if (!(adjacentTE instanceof BrassTunnelTileEntity))
return null; return null;
return (BrassTunnelTileEntity) adjacentTE; return (BrassTunnelTileEntity) adjacentTE;
@ -462,4 +542,33 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
return beltCapability; return beltCapability;
} }
public enum SelectionMode implements INamedIconOptions {
SPLIT(AllIcons.I_TUNNEL_SPLIT),
FORCED_SPLIT(AllIcons.I_TUNNEL_FORCED_SPLIT),
ROUND_ROBIN(AllIcons.I_TUNNEL_ROUND_ROBIN),
FORCED_ROUND_ROBIN(AllIcons.I_TUNNEL_FORCED_ROUND_ROBIN),
PREFER_NEAREST(AllIcons.I_TUNNEL_PREFER_NEAREST),
RANDOMIZE(AllIcons.I_TUNNEL_RANDOMIZE),
;
private final String translationKey;
private final AllIcons icon;
SelectionMode(AllIcons icon) {
this.icon = icon;
this.translationKey = "tunnel.selection_mode." + Lang.asId(name());
}
@Override
public AllIcons getIcon() {
return icon;
}
@Override
public String getTranslationKey() {
return translationKey;
}
}
} }

View file

@ -89,8 +89,9 @@ public class FunnelTileEntity extends SmartTileEntity {
if (!inputBehaviour.canInsertFromSide(facing)) if (!inputBehaviour.canInsertFromSide(facing))
return; return;
ItemStack stack = invManipulation.extract(-1, s -> inputBehaviour.handleInsertion(s, facing, true) ItemStack stack = invManipulation.extract(invManipulation.getAmountFromFilter(),
.isEmpty()); s -> inputBehaviour.handleInsertion(s, facing, true)
.isEmpty());
if (stack.isEmpty()) if (stack.isEmpty())
return; return;
flap(false); flap(false);
@ -127,7 +128,6 @@ public class FunnelTileEntity extends SmartTileEntity {
}); });
filtering.onlyActiveWhen(this::supportsFiltering); filtering.onlyActiveWhen(this::supportsFiltering);
behaviours.add(filtering); behaviours.add(filtering);
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput) behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
.setInsertionHandler(this::handleDirectBeltInput)); .setInsertionHandler(this::handleDirectBeltInput));
} }

View file

@ -1,30 +1,23 @@
package com.simibubi.create.content.logistics.block.inventories; package com.simibubi.create.content.logistics.block.inventories;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.inventory.ItemStackHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.NonNullList;
import net.minecraftforge.items.ItemStackHandler;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault; import javax.annotation.ParametersAreNonnullByDefault;
import mcp.MethodsReturnNonnullByDefault;
import net.minecraft.item.ItemStack;
import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.items.ItemStackHandler;
@MethodsReturnNonnullByDefault @MethodsReturnNonnullByDefault
@ParametersAreNonnullByDefault @ParametersAreNonnullByDefault
public class CreativeCrateInventory extends ItemStackHandler { public class CreativeCrateInventory extends ItemStackHandler {
private ItemStack filter = null;
private final CreativeCrateTileEntity te; private final CreativeCrateTileEntity te;
public CreativeCrateInventory(@Nullable CreativeCrateTileEntity te) { public CreativeCrateInventory(@Nullable CreativeCrateTileEntity te) {
this.te = te; this.te = te;
} }
public CreativeCrateInventory() {
this(null);
}
@Override @Override
public int getSlots() { public int getSlots() {
return 2; return 2;
@ -32,13 +25,14 @@ public class CreativeCrateInventory extends ItemStackHandler {
@Override @Override
public ItemStack getStackInSlot(int slot) { public ItemStack getStackInSlot(int slot) {
ItemStack stack = getProvidedItem();
if (slot == 1) if (slot == 1)
return ItemStack.EMPTY; return ItemStack.EMPTY;
if (getFilter() == null) if (stack == null)
return ItemStack.EMPTY; return ItemStack.EMPTY;
if (!getFilter().isEmpty()) if (!stack.isEmpty())
filter.setCount(filter.getMaxStackSize()); return ItemHandlerHelper.copyStackWithSize(stack, stack.getMaxStackSize());
return filter; return stack;
} }
@Override @Override
@ -48,16 +42,14 @@ public class CreativeCrateInventory extends ItemStackHandler {
@Override @Override
public ItemStack extractItem(int slot, int amount, boolean simulate) { public ItemStack extractItem(int slot, int amount, boolean simulate) {
if (getFilter() == null) ItemStack stack = getProvidedItem();
if (slot == 1)
return ItemStack.EMPTY; return ItemStack.EMPTY;
if (!getFilter().isEmpty()) if (stack == null)
filter.setCount(Math.min(getFilter().getMaxStackSize(), amount)); return ItemStack.EMPTY;
return getFilter(); if (!stack.isEmpty())
} return ItemHandlerHelper.copyStackWithSize(stack, Math.min(stack.getMaxStackSize(), amount));
return ItemStack.EMPTY;
@Override
public int getSlotLimit(int slot) {
return getStackInSlot(slot).getMaxStackSize();
} }
@Override @Override
@ -65,26 +57,10 @@ public class CreativeCrateInventory extends ItemStackHandler {
return true; return true;
} }
@Override
public CompoundNBT serializeNBT() {
CompoundNBT nbt = new CompoundNBT();
nbt.putBoolean("isCreativeCrate", true);
if (getFilter() != null)
ItemStackHelper.saveAllItems(nbt, NonNullList.from(ItemStack.EMPTY, getFilter()));
return nbt;
}
@Override
public void deserializeNBT(CompoundNBT nbt) {
NonNullList<ItemStack> filterList = NonNullList.withSize(1, ItemStack.EMPTY);
ItemStackHelper.loadAllItems(nbt, filterList);
filter = filterList.get(0);
}
@Nullable @Nullable
public ItemStack getFilter() { public ItemStack getProvidedItem() {
if (te != null) if (te != null)
filter = te.filter.getFilter(); return te.filter.getFilter();
return filter; return ItemStack.EMPTY;
} }
} }

View file

@ -1,5 +1,10 @@
package com.simibubi.create.content.logistics.block.mechanicalArm; package com.simibubi.create.content.logistics.block.mechanicalArm;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;
import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
@ -14,6 +19,7 @@ import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.NBTHelper; import com.simibubi.create.foundation.utility.NBTHelper;
import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.foundation.utility.VecHelper;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.JukeboxBlock; import net.minecraft.block.JukeboxBlock;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
@ -26,10 +32,6 @@ import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraftforge.common.util.Constants.NBT; import net.minecraftforge.common.util.Constants.NBT;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
public class ArmTileEntity extends KineticTileEntity { public class ArmTileEntity extends KineticTileEntity {
// Server // Server
@ -82,21 +84,8 @@ public class ArmTileEntity extends KineticTileEntity {
public void addBehaviours(List<TileEntityBehaviour> behaviours) { public void addBehaviours(List<TileEntityBehaviour> behaviours) {
super.addBehaviours(behaviours); super.addBehaviours(behaviours);
selectionMode = new ScrollOptionBehaviour<>(SelectionMode.class, Lang.translate("mechanical_arm.selection_mode"), this, selectionMode = new ScrollOptionBehaviour<>(SelectionMode.class,
new CenteredSideValueBoxTransform((blockState, direction) -> direction != Direction.DOWN && direction != Direction.UP) { Lang.translate("logistics.when_multiple_outputs_available"), this, new SelectionModeValueBox());
@Override
protected Vec3d getLocalOffset(BlockState state) {
int yPos = state.get(ArmBlock.CEILING) ? 16 - 3 : 3;
Vec3d location = VecHelper.voxelSpace(8, yPos, 14.5);
location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(getSide()), Direction.Axis.Y);
return location;
}
@Override
protected float getScale() {
return .3f;
}
});
selectionMode.requiresWrench(); selectionMode.requiresWrench();
behaviours.add(selectionMode); behaviours.add(selectionMode);
} }
@ -199,11 +188,13 @@ public class ArmTileEntity extends KineticTileEntity {
protected void searchForItem() { protected void searchForItem() {
boolean foundInput = false; boolean foundInput = false;
//for round robin, we start looking after the last used index, for default we start at 0; // for round robin, we start looking after the last used index, for default we
int startIndex = selectionMode.get() == SelectionMode.DEFAULT ? 0 : lastInputIndex + 1; // start at 0;
int startIndex = selectionMode.get() == SelectionMode.PREFER_FIRST ? 0 : lastInputIndex + 1;
//if we enforce round robin, only look at the next input in the list, otherwise, look at all inputs // if we enforce round robin, only look at the next input in the list,
int scanRange = selectionMode.get() == SelectionMode.ROUND_ROBIN_HARD ? lastInputIndex + 2 : inputs.size(); // otherwise, look at all inputs
int scanRange = selectionMode.get() == SelectionMode.FORCED_ROUND_ROBIN ? lastInputIndex + 2 : inputs.size();
if (scanRange > inputs.size()) if (scanRange > inputs.size())
scanRange = inputs.size(); scanRange = inputs.size();
@ -218,12 +209,13 @@ public class ArmTileEntity extends KineticTileEntity {
break InteractionPoints; break InteractionPoints;
} }
} }
if (!foundInput && selectionMode.get() == SelectionMode.ROUND_ROBIN_SOFT) { if (!foundInput && selectionMode.get() == SelectionMode.ROUND_ROBIN) {
//if we didn't find an input, but don't want to enforce round robin, reset the last index // if we didn't find an input, but don't want to enforce round robin, reset the
// last index
lastInputIndex = -1; lastInputIndex = -1;
} }
if (lastInputIndex == inputs.size() - 1) { if (lastInputIndex == inputs.size() - 1) {
//if we reached the last input in the list, reset the last index // if we reached the last input in the list, reset the last index
lastInputIndex = -1; lastInputIndex = -1;
} }
} }
@ -232,11 +224,13 @@ public class ArmTileEntity extends KineticTileEntity {
ItemStack held = heldItem.copy(); ItemStack held = heldItem.copy();
boolean foundOutput = false; boolean foundOutput = false;
//for round robin, we start looking after the last used index, for default we start at 0; // for round robin, we start looking after the last used index, for default we
int startIndex = selectionMode.get() == SelectionMode.DEFAULT ? 0 : lastOutputIndex + 1; // start at 0;
int startIndex = selectionMode.get() == SelectionMode.PREFER_FIRST ? 0 : lastOutputIndex + 1;
//if we enforce round robin, only look at the next index in the list, otherwise, look at all // if we enforce round robin, only look at the next index in the list,
int scanRange = selectionMode.get() == SelectionMode.ROUND_ROBIN_HARD ? lastOutputIndex + 2 : outputs.size(); // otherwise, look at all
int scanRange = selectionMode.get() == SelectionMode.FORCED_ROUND_ROBIN ? lastOutputIndex + 2 : outputs.size();
if (scanRange > outputs.size()) if (scanRange > outputs.size())
scanRange = outputs.size(); scanRange = outputs.size();
@ -251,17 +245,18 @@ public class ArmTileEntity extends KineticTileEntity {
break; break;
} }
if (!foundOutput && selectionMode.get() == SelectionMode.ROUND_ROBIN_SOFT) { if (!foundOutput && selectionMode.get() == SelectionMode.ROUND_ROBIN) {
//if we didn't find an input, but don't want to enforce round robin, reset the last index // if we didn't find an input, but don't want to enforce round robin, reset the
// last index
lastOutputIndex = -1; lastOutputIndex = -1;
} }
if (lastOutputIndex == outputs.size() - 1) { if (lastOutputIndex == outputs.size() - 1) {
//if we reached the last input in the list, reset the last index // if we reached the last input in the list, reset the last index
lastOutputIndex = -1; lastOutputIndex = -1;
} }
} }
//input == true => select input, false => select output // input == true => select input, false => select output
private void selectIndex(boolean input, int index) { private void selectIndex(boolean input, int index) {
phase = input ? Phase.MOVE_TO_INPUT : Phase.MOVE_TO_OUTPUT; phase = input ? Phase.MOVE_TO_INPUT : Phase.MOVE_TO_OUTPUT;
chasedPointIndex = index; chasedPointIndex = index;
@ -400,10 +395,31 @@ public class ArmTileEntity extends KineticTileEntity {
} }
} }
private class SelectionModeValueBox extends CenteredSideValueBoxTransform {
public SelectionModeValueBox() {
super((blockState, direction) -> direction != Direction.DOWN && direction != Direction.UP);
}
@Override
protected Vec3d getLocalOffset(BlockState state) {
int yPos = state.get(ArmBlock.CEILING) ? 16 - 3 : 3;
Vec3d location = VecHelper.voxelSpace(8, yPos, 14.5);
location = VecHelper.rotateCentered(location, AngleHelper.horizontalAngle(getSide()), Direction.Axis.Y);
return location;
}
@Override
protected float getScale() {
return .3f;
}
}
public enum SelectionMode implements INamedIconOptions { public enum SelectionMode implements INamedIconOptions {
DEFAULT(AllIcons.I_TOOL_MIRROR),//first valid interaction points gets used ROUND_ROBIN(AllIcons.I_ARM_ROUND_ROBIN),
ROUND_ROBIN_SOFT(AllIcons.I_TOOL_ROTATE),//attempt round robin, but skip invalid points FORCED_ROUND_ROBIN(AllIcons.I_ARM_FORCED_ROUND_ROBIN),
ROUND_ROBIN_HARD(AllIcons.I_TOOL_ROTATE),//enforce round robin, wait for invalid points to be ready again PREFER_FIRST(AllIcons.I_ARM_PREFER_FIRST),
; ;

View file

@ -76,11 +76,21 @@ public class AllIcons {
I_TOOL_DEPLOY = newRow(), I_TOOL_DEPLOY = newRow(),
I_SKIP_MISSING = next(), I_SKIP_MISSING = next(),
I_SKIP_TILES = next(), I_SKIP_TILES = next(),
I_DICE = next(),
I_TUNNEL_SPLIT = next(),
I_TUNNEL_FORCED_SPLIT = next(),
I_TUNNEL_ROUND_ROBIN = next(),
I_TUNNEL_FORCED_ROUND_ROBIN = next(),
I_TUNNEL_PREFER_NEAREST = next(),
I_TUNNEL_RANDOMIZE = next(),
I_TOOL_MOVE_XZ = newRow(), I_TOOL_MOVE_XZ = newRow(),
I_TOOL_MOVE_Y = next(), I_TOOL_MOVE_Y = next(),
I_TOOL_ROTATE = next(), I_TOOL_ROTATE = next(),
I_TOOL_MIRROR = next(), I_TOOL_MIRROR = next(),
I_ARM_ROUND_ROBIN = next(),
I_ARM_FORCED_ROUND_ROBIN = next(),
I_ARM_PREFER_FIRST = next(),
I_PLAY = newRow(), I_PLAY = newRow(),
I_PAUSE = next(), I_PAUSE = next(),

View file

@ -13,6 +13,7 @@ import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform;
import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform.Sided; import com.simibubi.create.foundation.tileEntity.behaviour.ValueBoxTransform.Sided;
import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.Pair;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
@ -75,7 +76,7 @@ public class FilteringRenderer {
.scrollTooltip(showCount ? "[" + Lang.translate("action.scroll") + "]" : "") .scrollTooltip(showCount ? "[" + Lang.translate("action.scroll") + "]" : "")
.passive(!hit); .passive(!hit);
CreateClient.outliner.showValueBox(pos, box.transform(behaviour.slotPositioning)) CreateClient.outliner.showValueBox(Pair.of("filter", pos), box.transform(behaviour.slotPositioning))
.lineWidth(1 / 64f) .lineWidth(1 / 64f)
.withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null)
.highlightFace(result.getFace()); .highlightFace(result.getFace());

View file

@ -117,7 +117,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
findNewCapability(); findNewCapability();
} }
protected int getAmountFromFilter() { public int getAmountFromFilter() {
int amount = -1; int amount = -1;
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE); FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
if (filter != null && !filter.anyAmount()) if (filter != null && !filter.anyAmount())

View file

@ -343,10 +343,18 @@
"create.tooltip.analogStrength": "Analog Strength: %1$s/15", "create.tooltip.analogStrength": "Analog Strength: %1$s/15",
"create.mechanical_arm.selection_mode": "Selection Mode", "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available",
"create.mechanical_arm.selection_mode.default": "First Valid Target",
"create.mechanical_arm.selection_mode.round_robin_soft": "Attempt Round Robin", "create.mechanical_arm.selection_mode.round_robin": "Round Robin",
"create.mechanical_arm.selection_mode.round_robin_hard": "Enforce Round Robin", "create.mechanical_arm.selection_mode.forced_round_robin": "Forced Round Robin",
"create.mechanical_arm.selection_mode.prefer_first": "Prefer First Target",
"create.tunnel.selection_mode.split": "Split",
"create.tunnel.selection_mode.forced_split": "Forced Split",
"create.tunnel.selection_mode.round_robin": "Round Robin",
"create.tunnel.selection_mode.forced_round_robin": "Forced Round Robin",
"create.tunnel.selection_mode.prefer_nearest": "Prefer Nearest",
"create.tunnel.selection_mode.randomize": "Randomize",
"create.gui.config.overlay1": "Hi :)", "create.gui.config.overlay1": "Hi :)",
"create.gui.config.overlay2": "This is a sample overlay", "create.gui.config.overlay2": "This is a sample overlay",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB