From 03cf4416747e52bd2225365e429cd8ed1c086e86 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Sun, 13 Sep 2020 22:00:11 +0200 Subject: [PATCH] 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 --- src/generated/resources/.cache/cache | 20 +- .../resources/assets/create/lang/en_us.json | 16 +- .../assets/create/lang/unfinished/de_de.json | 18 +- .../assets/create/lang/unfinished/fr_fr.json | 18 +- .../assets/create/lang/unfinished/it_it.json | 18 +- .../assets/create/lang/unfinished/ja_jp.json | 18 +- .../assets/create/lang/unfinished/ko_kr.json | 18 +- .../assets/create/lang/unfinished/nl_nl.json | 18 +- .../assets/create/lang/unfinished/pt_br.json | 18 +- .../assets/create/lang/unfinished/ru_ru.json | 18 +- .../assets/create/lang/unfinished/zh_cn.json | 18 +- .../structureMovement/MountedStorage.java | 10 +- .../relays/belt/BeltTileEntity.java | 13 +- .../belts/tunnel/BrassTunnelTileEntity.java | 183 ++++++++++++++---- .../block/funnel/FunnelTileEntity.java | 6 +- .../inventories/CreativeCrateInventory.java | 64 ++---- .../block/mechanicalArm/ArmTileEntity.java | 98 ++++++---- .../create/foundation/gui/AllIcons.java | 10 + .../filtering/FilteringRenderer.java | 3 +- .../inventory/InvManipulationBehaviour.java | 2 +- .../assets/create/lang/default/messages.json | 16 +- .../assets/create/textures/gui/icons.png | Bin 4163 -> 4411 bytes 22 files changed, 398 insertions(+), 205 deletions(-) diff --git a/src/generated/resources/.cache/cache b/src/generated/resources/.cache/cache index 610ff072e..2a50961a2 100644 --- a/src/generated/resources/.cache/cache +++ b/src/generated/resources/.cache/cache @@ -350,16 +350,16 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j 7f39521b211441f5c3e06d60c5978cebe16cacfb assets/create/blockstates/zinc_block.json b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json c87674f2935327f78657f1bb44b3b10b6697a548 assets/create/lang/en_ud.json -ec8fc3f55847ad667752fdc06fc8b5de75253cf4 assets/create/lang/en_us.json -bab998d2bbb0e24147e8dd34006bf94a4ad857e7 assets/create/lang/unfinished/de_de.json -e3e51ea8e3e540a4f363610195050b0bbe8b452d assets/create/lang/unfinished/fr_fr.json -b2bc925b69b276f03dbb30aa996e3b8677c9eb16 assets/create/lang/unfinished/it_it.json -272aa6f6567b451a5204283f580f642990c04ce0 assets/create/lang/unfinished/ja_jp.json -1e3115cbbdcb55dfa871ae31fc88cea78544fc5a assets/create/lang/unfinished/ko_kr.json -e470b095bfc10d3fa7141a4d8860eaf093be9e62 assets/create/lang/unfinished/nl_nl.json -1c3f2f8cf9d7d5280d7495da3b8c89481fd5dcee assets/create/lang/unfinished/pt_br.json -a49430d7b66c52cde1880ccb7fd6123fb5ab2b2b assets/create/lang/unfinished/ru_ru.json -5d569d86a3d8af114bb6b99a6410c3823d2191f8 assets/create/lang/unfinished/zh_cn.json +0e38385f3de32bfc0f5d3d90dfa635469e953e43 assets/create/lang/en_us.json +cb59266eb110493f41cd8754915e2c2626063742 assets/create/lang/unfinished/de_de.json +9f1f8ebf3683613729f0c4d62d12d3146cfdb634 assets/create/lang/unfinished/fr_fr.json +a6d24acb90e85ed13a5bd36a4e95750319a01de5 assets/create/lang/unfinished/it_it.json +5dbd2b38becc4e985cc926bab5c58e8c7dfaf7e7 assets/create/lang/unfinished/ja_jp.json +4065e282b5860497090e86b3bdf2773f9888f502 assets/create/lang/unfinished/ko_kr.json +e1baa1589c53467ca2f610c3f0cc51c861afdcff assets/create/lang/unfinished/nl_nl.json +8590ef541ece9eae76135b3e93c53798b3d37aac assets/create/lang/unfinished/pt_br.json +7b67a7b85631c83f6803eb717bced55d0efb76b7 assets/create/lang/unfinished/ru_ru.json +29a47e6bc1f85467af17f97d30e2e0100bea99ea assets/create/lang/unfinished/zh_cn.json 846200eb548d3bfa2e77b41039de159b4b6cfb45 assets/create/models/block/acacia_window.json 1930fa3a3c98d53dd19e4ee7f55bc27fd47aa281 assets/create/models/block/acacia_window_pane_noside.json 1763ea2c9b981d187f5031ba608f3d5d3be3986a assets/create/models/block/acacia_window_pane_noside_alt.json diff --git a/src/generated/resources/assets/create/lang/en_us.json b/src/generated/resources/assets/create/lang/en_us.json index 4e2eea479..51f581b80 100644 --- a/src/generated/resources/assets/create/lang/en_us.json +++ b/src/generated/resources/assets/create/lang/en_us.json @@ -836,10 +836,18 @@ "create.tooltip.generationSpeed": "Generates at %1$s %2$s", "create.tooltip.analogStrength": "Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "Selection Mode", - "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_hard": "Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "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.overlay2": "This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/de_de.json b/src/generated/resources/assets/create/lang/unfinished/de_de.json index ecc10a864..c58938a1d 100644 --- a/src/generated/resources/assets/create/lang/unfinished/de_de.json +++ b/src/generated/resources/assets/create/lang/unfinished/de_de.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 794", + "_": "Missing Localizations: 800", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json index 4ae72401e..2ac436d6a 100644 --- a/src/generated/resources/assets/create/lang/unfinished/fr_fr.json +++ b/src/generated/resources/assets/create/lang/unfinished/fr_fr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 418", + "_": "Missing Localizations: 424", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "Génère à %1$s %2$s", "create.tooltip.analogStrength": "Force analogique: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/it_it.json b/src/generated/resources/assets/create/lang/unfinished/it_it.json index 3002b4fc4..28ef50685 100644 --- a/src/generated/resources/assets/create/lang/unfinished/it_it.json +++ b/src/generated/resources/assets/create/lang/unfinished/it_it.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 402", + "_": "Missing Localizations: 408", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "Genera %1$s %2$s", "create.tooltip.analogStrength": "Forza Analogica: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json index f9ffe954c..8ffdeb2e8 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ja_jp.json +++ b/src/generated/resources/assets/create/lang/unfinished/ja_jp.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 397", + "_": "Missing Localizations: 403", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "%1$s %2$sを生成", "create.tooltip.analogStrength": "アナログ強度: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json index f6fe5f1b0..6f6e67b5c 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ko_kr.json +++ b/src/generated/resources/assets/create/lang/unfinished/ko_kr.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 402", + "_": "Missing Localizations: 408", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "%1$s %2$s만큼 발전함", "create.tooltip.analogStrength": "레드스톤 출력: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json index 021ecce9e..3689e2c23 100644 --- a/src/generated/resources/assets/create/lang/unfinished/nl_nl.json +++ b/src/generated/resources/assets/create/lang/unfinished/nl_nl.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 732", + "_": "Missing Localizations: 738", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/pt_br.json b/src/generated/resources/assets/create/lang/unfinished/pt_br.json index 64fce4d6d..38dab76bd 100644 --- a/src/generated/resources/assets/create/lang/unfinished/pt_br.json +++ b/src/generated/resources/assets/create/lang/unfinished/pt_br.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 801", + "_": "Missing Localizations: 807", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json index b10bb0dee..21717a198 100644 --- a/src/generated/resources/assets/create/lang/unfinished/ru_ru.json +++ b/src/generated/resources/assets/create/lang/unfinished/ru_ru.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 795", + "_": "Missing Localizations: 801", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s", "create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json index 69da95740..db7543fac 100644 --- a/src/generated/resources/assets/create/lang/unfinished/zh_cn.json +++ b/src/generated/resources/assets/create/lang/unfinished/zh_cn.json @@ -1,5 +1,5 @@ { - "_": "Missing Localizations: 82", + "_": "Missing Localizations: 88", "_": "->------------------------] Game Elements [------------------------<-", @@ -837,10 +837,18 @@ "create.tooltip.generationSpeed": "产生 %1$s %2$s", "create.tooltip.analogStrength": "调节强度: %1$s/15", - "create.mechanical_arm.selection_mode": "UNLOCALIZED: Selection Mode", - "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_hard": "UNLOCALIZED: Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: 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.overlay2": "UNLOCALIZED: This is a sample overlay", diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java index 27e3df9bc..a6329a37a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/MountedStorage.java @@ -3,7 +3,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement; import com.simibubi.create.AllTileEntities; 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.item.ItemStack; import net.minecraft.nbt.CompoundNBT; @@ -86,17 +85,14 @@ public class MountedStorage { public MountedStorage(CompoundNBT nbt) { handler = new ItemStackHandler(); working = nbt != null; - if (working) { - if (nbt.contains("isCreativeCrate") && nbt.getBoolean("isCreativeCrate")) - handler = new CreativeCrateInventory(); + if (working) handler.deserializeNBT(nbt); - } } public void fill(TileEntity te) { IItemHandler teHandler = te.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) .orElse(dummyHandler); - if (teHandler != dummyHandler && teHandler instanceof IItemHandlerModifiable && !(teHandler instanceof CreativeCrateInventory)) { + if (teHandler != dummyHandler && teHandler instanceof IItemHandlerModifiable) { IItemHandlerModifiable inv = (IItemHandlerModifiable) teHandler; for (int slot = 0; slot < Math.min(inv.getSlots(), handler.getSlots()); slot++) inv.setStackInSlot(slot, handler.getStackInSlot(slot)); @@ -120,8 +116,6 @@ public class MountedStorage { return false; if (AllTileEntities.ADJUSTABLE_CRATE.is(te)) return true; - if (AllTileEntities.CREATIVE_CRATE.is(te)) - return true; if (te instanceof ShulkerBoxTileEntity) return true; if (te instanceof ChestTileEntity) diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 6528e2316..4229d67b7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -80,7 +80,8 @@ public class BeltTileEntity extends KineticTileEntity { @Override public void addBehaviours(List 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) .withStackPlacement(this::getWorldPositionOf)); } @@ -383,12 +384,10 @@ public class BeltTileEntity extends KineticTileEntity { sendData(); } - /** - * always target a DirectBeltInsertionBehaviour - */ - @Deprecated - public boolean tryInsertingFromSide(Direction side, ItemStack stack, boolean simulate) { - return tryInsertingFromSide(new TransportedItemStack(stack), side, simulate).isEmpty(); + private boolean canInsertFrom(Direction side) { + if (getSpeed() == 0) + return false; + return getMovementFacing() != side.getOpposite(); } private ItemStack tryInsertingFromSide(TransportedItemStack transportedStack, Direction side, boolean simulate) { diff --git a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java index 53f6f312d..e3a5c0fb4 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/belts/tunnel/BrassTunnelTileEntity.java @@ -2,6 +2,7 @@ package com.simibubi.create.content.logistics.block.belts.tunnel; import java.util.ArrayList; import java.util.List; +import java.util.Random; 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.BeltTileEntity; 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.behaviour.CenteredSideValueBoxTransform; 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.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.Lang; import com.simibubi.create.foundation.utility.NBTHelper; 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.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; +import net.minecraftforge.items.ItemHandlerHelper; public class BrassTunnelTileEntity extends BeltTunnelTileEntity { @@ -49,7 +56,9 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { List> distributionTargets; int distributionDistanceLeft; int distributionDistanceRight; + int previousOutputIndex; + protected ScrollOptionBehaviour selectionMode; private LazyOptional beltCapability; private LazyOptional tunnelCapability; @@ -59,6 +68,27 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { stackToDistribute = ItemStack.EMPTY; beltCapability = LazyOptional.empty(); tunnelCapability = LazyOptional.of(() -> new BrassTunnelItemHandler(this)); + previousOutputIndex = 0; + } + + @Override + public void addBehaviours(List 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 @@ -66,6 +96,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { super.tick(); BeltTileEntity beltBelow = BeltHelper.getSegmentTE(world, pos.down()); + if (distributionProgress > 0) + distributionProgress--; if (beltBelow == null || beltBelow.getSpeed() == 0) return; if (stackToDistribute.isEmpty()) @@ -80,7 +112,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { for (Pair pair : gatherValidOutputs()) { BrassTunnelTileEntity tunnel = pair.getKey(); Direction output = pair.getValue(); - if (!insertIntoTunnel(tunnel, output, stackToDistribute, true).isEmpty()) + if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null) continue; distributionTargets.add(Pair.of(tunnel.pos, output)); int distance = tunnel.pos.getX() + tunnel.pos.getZ() - pos.getX() - pos.getZ(); @@ -93,12 +125,11 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { if (distributionTargets.isEmpty()) return; - distributionProgress = 0; + distributionProgress = 10; sendData(); return; } - // TODO this is instant for now if (distributionProgress == 0) { List> validTargets = new ArrayList<>(); for (Pair pair : distributionTargets) { @@ -110,36 +141,73 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { validTargets.add(Pair.of((BrassTunnelTileEntity) te, output)); } - if (validTargets.size() == 0) { - distributionProgress = -1; - sendData(); - return; - } - - int stackSizeBefore = stackToDistribute.getCount(); - int stackSizeForOutput = stackSizeBefore / validTargets.size(); - int remainder = stackSizeBefore % validTargets.size(); - - for (Pair 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--; - } - + distribute(validTargets); distributionProgress = -1; - markDirty(); - sendData(); return; } } + private static Random rand = new Random(); + + private void distribute(List> 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 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) { stackToDistribute = stack; distributionProgress = -1; @@ -151,21 +219,24 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { return stackToDistribute; } + @Nullable protected ItemStack insertIntoTunnel(BrassTunnelTileEntity tunnel, Direction side, ItemStack stack, boolean simulate) { if (stack.isEmpty()) return stack; if (!tunnel.testFlapFilter(side, stack)) - return stack; + return null; BeltTileEntity below = BeltHelper.getSegmentTE(world, tunnel.pos.down()); if (below == null) - return stack; + return null; BlockPos offset = tunnel.getPos() .down() .offset(side); DirectBeltInputBehaviour sideOutput = TileEntityBehaviour.get(world, offset, DirectBeltInputBehaviour.TYPE); if (sideOutput != null) { + if (!sideOutput.canInsertFromSide(side)) + return null; ItemStack result = sideOutput.handleInsertion(stack, side, simulate); if (result.isEmpty() && !simulate) tunnel.flap(side, true); @@ -177,8 +248,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { if (!Block.hasSolidSide(world.getBlockState(offset), world, offset, side.getOpposite())) { BeltTileEntity controllerTE = below.getControllerTE(); if (controllerTE == null) - return stack; - + return null; + if (!simulate) { tunnel.flap(side, true); ItemStack ejected = stack; @@ -195,11 +266,11 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { entity.velocityChanged = true; world.addEntity(entity); } - + return ItemStack.EMPTY; } - return stack; + return null; } public boolean testFlapFilter(Direction side, ItemStack stack) { @@ -334,6 +405,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { compound.put("StackToDistribute", stackToDistribute.serializeNBT()); compound.putFloat("DistributionProgress", distributionProgress); + compound.putInt("PreviousIndex", previousOutputIndex); compound.putInt("DistanceLeft", distributionDistanceLeft); compound.putInt("DistanceRight", distributionDistanceRight); compound.put("Targets", NBTHelper.writeCompoundList(distributionTargets, pair -> { @@ -351,11 +423,12 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { protected void read(CompoundNBT compound, boolean clientPacket) { boolean wasConnectedLeft = connectedLeft; boolean wasConnectedRight = connectedRight; - + connectedLeft = compound.getBoolean("ConnectedLeft"); connectedRight = compound.getBoolean("ConnectedRight"); stackToDistribute = ItemStack.read(compound.getCompound("StackToDistribute")); distributionProgress = compound.getFloat("DistributionProgress"); + previousOutputIndex = compound.getInt("PreviousIndex"); distributionDistanceLeft = compound.getInt("DistanceLeft"); distributionDistanceRight = compound.getInt("DistanceRight"); distributionTargets = NBTHelper.readCompoundList(compound.getList("Targets", NBT.TAG_COMPOUND), nbt -> { @@ -365,7 +438,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { }); super.read(compound, clientPacket); - + if (!clientPacket) return; if (wasConnectedLeft != connectedLeft || wasConnectedRight != connectedRight) { @@ -391,15 +464,20 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { connectedLeft = nowConnectedLeft; connectivityChanged = true; BrassTunnelTileEntity adjacent = getAdjacent(true); - if (adjacent != null && !world.isRemote) + if (adjacent != null && !world.isRemote) { adjacent.updateTunnelConnections(); + adjacent.selectionMode.setValue(selectionMode.getValue()); + } } + if (connectedRight != nowConnectedRight) { connectedRight = nowConnectedRight; connectivityChanged = true; BrassTunnelTileEntity adjacent = getAdjacent(false); - if (adjacent != null && !world.isRemote) + if (adjacent != null && !world.isRemote) { adjacent.updateTunnelConnections(); + adjacent.selectionMode.setValue(selectionMode.getValue()); + } } if (filtering != null) @@ -435,6 +513,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { if (adjacentBlockState.get(BrassTunnelBlock.HORIZONTAL_AXIS) != axis) return null; TileEntity adjacentTE = world.getTileEntity(adjacentPos); + if (adjacentTE.isRemoved()) + return null; if (!(adjacentTE instanceof BrassTunnelTileEntity)) return null; return (BrassTunnelTileEntity) adjacentTE; @@ -462,4 +542,33 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity { 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; + } + } + } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java index eeb479660..0f2541fc1 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/funnel/FunnelTileEntity.java @@ -89,8 +89,9 @@ public class FunnelTileEntity extends SmartTileEntity { if (!inputBehaviour.canInsertFromSide(facing)) return; - ItemStack stack = invManipulation.extract(-1, s -> inputBehaviour.handleInsertion(s, facing, true) - .isEmpty()); + ItemStack stack = invManipulation.extract(invManipulation.getAmountFromFilter(), + s -> inputBehaviour.handleInsertion(s, facing, true) + .isEmpty()); if (stack.isEmpty()) return; flap(false); @@ -127,7 +128,6 @@ public class FunnelTileEntity extends SmartTileEntity { }); filtering.onlyActiveWhen(this::supportsFiltering); behaviours.add(filtering); - behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput) .setInsertionHandler(this::handleDirectBeltInput)); } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateInventory.java b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateInventory.java index 64e568da7..9b6736fef 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateInventory.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/inventories/CreativeCrateInventory.java @@ -1,30 +1,23 @@ 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.ParametersAreNonnullByDefault; +import mcp.MethodsReturnNonnullByDefault; +import net.minecraft.item.ItemStack; +import net.minecraftforge.items.ItemHandlerHelper; +import net.minecraftforge.items.ItemStackHandler; + @MethodsReturnNonnullByDefault @ParametersAreNonnullByDefault public class CreativeCrateInventory extends ItemStackHandler { - private ItemStack filter = null; private final CreativeCrateTileEntity te; public CreativeCrateInventory(@Nullable CreativeCrateTileEntity te) { this.te = te; } - public CreativeCrateInventory() { - this(null); - } - @Override public int getSlots() { return 2; @@ -32,13 +25,14 @@ public class CreativeCrateInventory extends ItemStackHandler { @Override public ItemStack getStackInSlot(int slot) { + ItemStack stack = getProvidedItem(); if (slot == 1) return ItemStack.EMPTY; - if (getFilter() == null) + if (stack == null) return ItemStack.EMPTY; - if (!getFilter().isEmpty()) - filter.setCount(filter.getMaxStackSize()); - return filter; + if (!stack.isEmpty()) + return ItemHandlerHelper.copyStackWithSize(stack, stack.getMaxStackSize()); + return stack; } @Override @@ -48,16 +42,14 @@ public class CreativeCrateInventory extends ItemStackHandler { @Override public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (getFilter() == null) + ItemStack stack = getProvidedItem(); + if (slot == 1) return ItemStack.EMPTY; - if (!getFilter().isEmpty()) - filter.setCount(Math.min(getFilter().getMaxStackSize(), amount)); - return getFilter(); - } - - @Override - public int getSlotLimit(int slot) { - return getStackInSlot(slot).getMaxStackSize(); + if (stack == null) + return ItemStack.EMPTY; + if (!stack.isEmpty()) + return ItemHandlerHelper.copyStackWithSize(stack, Math.min(stack.getMaxStackSize(), amount)); + return ItemStack.EMPTY; } @Override @@ -65,26 +57,10 @@ public class CreativeCrateInventory extends ItemStackHandler { 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 filterList = NonNullList.withSize(1, ItemStack.EMPTY); - ItemStackHelper.loadAllItems(nbt, filterList); - filter = filterList.get(0); - } - @Nullable - public ItemStack getFilter() { + public ItemStack getProvidedItem() { if (te != null) - filter = te.filter.getFilter(); - return filter; + return te.filter.getFilter(); + return ItemStack.EMPTY; } } diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java index 9d5784e50..c7e17c488 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmTileEntity.java @@ -1,5 +1,10 @@ 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.logistics.block.mechanicalArm.ArmInteractionPoint.Jukebox; 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.NBTHelper; import com.simibubi.create.foundation.utility.VecHelper; + import net.minecraft.block.BlockState; import net.minecraft.block.JukeboxBlock; import net.minecraft.item.ItemStack; @@ -26,10 +32,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import net.minecraftforge.common.util.Constants.NBT; -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; - public class ArmTileEntity extends KineticTileEntity { // Server @@ -82,21 +84,8 @@ public class ArmTileEntity extends KineticTileEntity { public void addBehaviours(List behaviours) { super.addBehaviours(behaviours); - selectionMode = new ScrollOptionBehaviour<>(SelectionMode.class, Lang.translate("mechanical_arm.selection_mode"), this, - new CenteredSideValueBoxTransform((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; - } - }); + selectionMode = new ScrollOptionBehaviour<>(SelectionMode.class, + Lang.translate("logistics.when_multiple_outputs_available"), this, new SelectionModeValueBox()); selectionMode.requiresWrench(); behaviours.add(selectionMode); } @@ -177,7 +166,7 @@ public class ArmTileEntity extends KineticTileEntity { lowerArmAngle.set(MathHelper.lerp(progress, previousTarget.lowerArmAngle, target.lowerArmAngle)); upperArmAngle.set(MathHelper.lerp(progress, previousTarget.upperArmAngle, target.upperArmAngle)); - + headAngle.set(AngleHelper.angleLerp(progress, previousTarget.headAngle % 360, target.headAngle % 360)); } @@ -199,11 +188,13 @@ public class ArmTileEntity extends KineticTileEntity { protected void searchForItem() { boolean foundInput = false; - //for round robin, we start looking after the last used index, for default we start at 0; - int startIndex = selectionMode.get() == SelectionMode.DEFAULT ? 0 : lastInputIndex + 1; + // for round robin, we start looking after the last used index, for default we + // 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 - int scanRange = selectionMode.get() == SelectionMode.ROUND_ROBIN_HARD ? lastInputIndex + 2 : inputs.size(); + // if we enforce round robin, only look at the next input in the list, + // otherwise, look at all inputs + int scanRange = selectionMode.get() == SelectionMode.FORCED_ROUND_ROBIN ? lastInputIndex + 2 : inputs.size(); if (scanRange > inputs.size()) scanRange = inputs.size(); @@ -218,12 +209,13 @@ public class ArmTileEntity extends KineticTileEntity { break InteractionPoints; } } - if (!foundInput && selectionMode.get() == SelectionMode.ROUND_ROBIN_SOFT) { - //if we didn't find an input, but don't want to enforce round robin, reset the last index + 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 lastInputIndex = -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; } } @@ -232,11 +224,13 @@ public class ArmTileEntity extends KineticTileEntity { ItemStack held = heldItem.copy(); boolean foundOutput = false; - //for round robin, we start looking after the last used index, for default we start at 0; - int startIndex = selectionMode.get() == SelectionMode.DEFAULT ? 0 : lastOutputIndex + 1; + // for round robin, we start looking after the last used index, for default we + // 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 - int scanRange = selectionMode.get() == SelectionMode.ROUND_ROBIN_HARD ? lastOutputIndex + 2 : outputs.size(); + // if we enforce round robin, only look at the next index in the list, + // otherwise, look at all + int scanRange = selectionMode.get() == SelectionMode.FORCED_ROUND_ROBIN ? lastOutputIndex + 2 : outputs.size(); if (scanRange > outputs.size()) scanRange = outputs.size(); @@ -251,17 +245,18 @@ public class ArmTileEntity extends KineticTileEntity { break; } - if (!foundOutput && selectionMode.get() == SelectionMode.ROUND_ROBIN_SOFT) { - //if we didn't find an input, but don't want to enforce round robin, reset the last index + 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 lastOutputIndex = -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; } } - //input == true => select input, false => select output + // input == true => select input, false => select output private void selectIndex(boolean input, int index) { phase = input ? Phase.MOVE_TO_INPUT : Phase.MOVE_TO_OUTPUT; chasedPointIndex = index; @@ -373,17 +368,17 @@ public class ArmTileEntity extends KineticTileEntity { int previousIndex = chasedPointIndex; Phase previousPhase = phase; ListNBT interactionPointTagBefore = interactionPointTag; - + super.read(compound, clientPacket); heldItem = ItemStack.read(compound.getCompound("HeldItem")); phase = NBTHelper.readEnum(compound, "Phase", Phase.class); chasedPointIndex = compound.getInt("TargetPointIndex"); chasedPointProgress = compound.getFloat("MovementProgress"); interactionPointTag = compound.getList("InteractionPoints", NBT.TAG_COMPOUND); - + if (!clientPacket) return; - + boolean ceiling = isOnCeiling(); if (interactionPointTagBefore == null || interactionPointTagBefore.size() != interactionPointTag.size()) updateInteractionPoints = true; @@ -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 { - DEFAULT(AllIcons.I_TOOL_MIRROR),//first valid interaction points gets used - ROUND_ROBIN_SOFT(AllIcons.I_TOOL_ROTATE),//attempt round robin, but skip invalid points - ROUND_ROBIN_HARD(AllIcons.I_TOOL_ROTATE),//enforce round robin, wait for invalid points to be ready again + ROUND_ROBIN(AllIcons.I_ARM_ROUND_ROBIN), + FORCED_ROUND_ROBIN(AllIcons.I_ARM_FORCED_ROUND_ROBIN), + PREFER_FIRST(AllIcons.I_ARM_PREFER_FIRST), ; diff --git a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java index 28dc9bea8..c697cc6c9 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java +++ b/src/main/java/com/simibubi/create/foundation/gui/AllIcons.java @@ -76,11 +76,21 @@ public class AllIcons { I_TOOL_DEPLOY = newRow(), I_SKIP_MISSING = 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_Y = next(), I_TOOL_ROTATE = 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_PAUSE = next(), diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java index 4d547a381..fc46cc4b1 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/filtering/FilteringRenderer.java @@ -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.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; +import com.simibubi.create.foundation.utility.Pair; import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; @@ -75,7 +76,7 @@ public class FilteringRenderer { .scrollTooltip(showCount ? "[" + Lang.translate("action.scroll") + "]" : "") .passive(!hit); - CreateClient.outliner.showValueBox(pos, box.transform(behaviour.slotPositioning)) + CreateClient.outliner.showValueBox(Pair.of("filter", pos), box.transform(behaviour.slotPositioning)) .lineWidth(1 / 64f) .withFaceTexture(hit ? AllSpecialTextures.THIN_CHECKERED : null) .highlightFace(result.getFace()); diff --git a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java index 93028ca0d..971cd932d 100644 --- a/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java +++ b/src/main/java/com/simibubi/create/foundation/tileEntity/behaviour/inventory/InvManipulationBehaviour.java @@ -117,7 +117,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour { findNewCapability(); } - protected int getAmountFromFilter() { + public int getAmountFromFilter() { int amount = -1; FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE); if (filter != null && !filter.anyAmount()) diff --git a/src/main/resources/assets/create/lang/default/messages.json b/src/main/resources/assets/create/lang/default/messages.json index 94fb3516b..26b6c12c0 100644 --- a/src/main/resources/assets/create/lang/default/messages.json +++ b/src/main/resources/assets/create/lang/default/messages.json @@ -343,10 +343,18 @@ "create.tooltip.analogStrength": "Analog Strength: %1$s/15", - "create.mechanical_arm.selection_mode": "Selection Mode", - "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_hard": "Enforce Round Robin", + "create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available", + + "create.mechanical_arm.selection_mode.round_robin": "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.overlay2": "This is a sample overlay", diff --git a/src/main/resources/assets/create/textures/gui/icons.png b/src/main/resources/assets/create/textures/gui/icons.png index 06aa1ce240b58cd034610eb2b430b161c20fe611..42b3e34333438cdda3401e8b1b71d6cda55468b9 100644 GIT binary patch delta 4191 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 Ie_i?Q-vIf^0RR91 delta 3940 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