Logistics' final stretch, Part I
- Brass tunnels once again have the ability to synchronize inputs among a chain - Mechanical arms now have a range limitation - Mechanical arms now wait with initialization until their area is fully loaded - Chutes no longer ignore the direction of an attached fans air flow - Chutes now render particles indicating their movement direction - Chutes can now pull items up from belts or off the ground - Fixed item model of shadow casing - Fixed invisible quads under funnels when no casing is applied to the belt - Belt mounted funnels can now be perpendicular to the belt theyre on - Funnels can now transpose items like a hopper when facing down
This commit is contained in:
parent
f58a7c8482
commit
990d80412e
59 changed files with 864 additions and 250 deletions
|
@ -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
|
||||
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
|
||||
62a4c9e5454fd6e899495c95d6fddd020d472bc7 assets/create/lang/en_us.json
|
||||
42081320880e3248cc1e7e667d38bb3be682790a assets/create/lang/unfinished/de_de.json
|
||||
8fc3d8467436b5dd9221b0ed72b1a64bf83d0767 assets/create/lang/unfinished/fr_fr.json
|
||||
a5125e0ca8bb93c7c4f11d49a80a155a7ea14b16 assets/create/lang/unfinished/it_it.json
|
||||
b173b6500f8a675e266864310ab8e205721dbe12 assets/create/lang/unfinished/ja_jp.json
|
||||
1af8e96a3129f8aac458b75eff69378a0cc9dd7d assets/create/lang/unfinished/ko_kr.json
|
||||
343a4455ca0f29b2ae6ac439030c0dfde0e4c59b assets/create/lang/unfinished/nl_nl.json
|
||||
d7bd8d85e3b8def1b4fe72da0a43845d1bb61c1c assets/create/lang/unfinished/pt_br.json
|
||||
6e7fdb53ae3121e5575021bb224d1bfbe257c38b assets/create/lang/unfinished/ru_ru.json
|
||||
1a3e1309d92024445dae821d25168dab74ff5cdd 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
|
||||
|
|
|
@ -836,6 +836,10 @@
|
|||
"create.tooltip.generationSpeed": "Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "%1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "Round Robin",
|
||||
|
@ -848,6 +852,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 800",
|
||||
"_": "Missing Localizations: 804",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 424",
|
||||
"_": "Missing Localizations: 428",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "Génère à %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "Force analogique: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 408",
|
||||
"_": "Missing Localizations: 412",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "Genera %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "Forza Analogica: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 403",
|
||||
"_": "Missing Localizations: 407",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "%1$s %2$sを生成",
|
||||
"create.tooltip.analogStrength": "アナログ強度: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 408",
|
||||
"_": "Missing Localizations: 412",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "%1$s %2$s만큼 발전함",
|
||||
"create.tooltip.analogStrength": "레드스톤 출력: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 738",
|
||||
"_": "Missing Localizations: 742",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 807",
|
||||
"_": "Missing Localizations: 811",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 801",
|
||||
"_": "Missing Localizations: 805",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "UNLOCALIZED: Generates at %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "UNLOCALIZED: Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"_": "Missing Localizations: 88",
|
||||
"_": "Missing Localizations: 92",
|
||||
|
||||
"_": "->------------------------] Game Elements [------------------------<-",
|
||||
|
||||
|
@ -837,6 +837,10 @@
|
|||
"create.tooltip.generationSpeed": "产生 %1$s %2$s",
|
||||
"create.tooltip.analogStrength": "调节强度: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "UNLOCALIZED: Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "UNLOCALIZED: Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "UNLOCALIZED: %1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"create.logistics.when_multiple_outputs_available": "UNLOCALIZED: When Multiple Outputs Available",
|
||||
|
||||
"create.mechanical_arm.selection_mode.round_robin": "UNLOCALIZED: Round Robin",
|
||||
|
@ -849,6 +853,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "UNLOCALIZED: Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "UNLOCALIZED: Hi :)",
|
||||
"create.gui.config.overlay2": "UNLOCALIZED: This is a sample overlay",
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.simibubi.create;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import com.simibubi.create.content.contraptions.particle.AirFlowParticleData;
|
||||
import com.simibubi.create.content.contraptions.particle.AirParticleData;
|
||||
import com.simibubi.create.content.contraptions.particle.CubeParticle;
|
||||
import com.simibubi.create.content.contraptions.particle.CubeParticleData;
|
||||
import com.simibubi.create.content.contraptions.particle.HeaterParticleData;
|
||||
|
@ -26,6 +27,7 @@ public enum AllParticleTypes {
|
|||
|
||||
ROTATION_INDICATOR(RotationIndicatorParticleData::new),
|
||||
AIR_FLOW(AirFlowParticleData::new),
|
||||
AIR(AirParticleData::new),
|
||||
HEATER_PARTICLE(HeaterParticleData::new),
|
||||
CUBE(CubeParticleData::dummy, () -> CubeParticle.Factory::new)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.simibubi.create;
|
||||
|
||||
import com.simibubi.create.foundation.command.ChunkUtil;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import java.util.Random;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -15,6 +15,7 @@ import com.simibubi.create.content.palettes.PalettesItemGroup;
|
|||
import com.simibubi.create.content.schematics.ServerSchematicLoader;
|
||||
import com.simibubi.create.foundation.advancement.AllAdvancements;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.command.ChunkUtil;
|
||||
import com.simibubi.create.foundation.command.ServerLagger;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.data.CreateRegistrate;
|
||||
|
@ -34,6 +35,7 @@ import net.minecraft.particles.ParticleType;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.SoundEvent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.EventPriority;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
|
@ -62,6 +64,7 @@ public class Create {
|
|||
public static TorquePropagator torquePropagator;
|
||||
public static ServerLagger lagger;
|
||||
public static ChunkUtil chunkUtil;
|
||||
public static Random random;
|
||||
|
||||
private static final NonNullLazyValue<CreateRegistrate> registrate = CreateRegistrate.lazy(ID);
|
||||
|
||||
|
@ -87,6 +90,7 @@ public class Create {
|
|||
modEventBus.addListener(EventPriority.LOWEST, this::gatherData);
|
||||
|
||||
AllConfigs.register();
|
||||
random = new Random();
|
||||
|
||||
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> CreateClient.addClientListeners(modEventBus));
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
public void blockChanged() {
|
||||
removeBehaviour(InvManipulationBehaviour.TYPE);
|
||||
inserting = new InvManipulationBehaviour(this, this::getTargetFace);
|
||||
putBehaviour(inserting);
|
||||
attachBehaviourLate(inserting);
|
||||
}
|
||||
|
||||
public BlockFace getTargetFace(World world, BlockPos pos, BlockState state) {
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.content.contraptions.components.deployer;
|
|||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -132,7 +131,7 @@ public class DeployerItemHandler implements IItemHandlerModifiable {
|
|||
|
||||
@Override
|
||||
public boolean isItemValid(int slot, ItemStack stack) {
|
||||
FilteringBehaviour filteringBehaviour = TileEntityBehaviour.get(te, FilteringBehaviour.TYPE);
|
||||
FilteringBehaviour filteringBehaviour = te.getBehaviour(FilteringBehaviour.TYPE);
|
||||
return filteringBehaviour == null || filteringBehaviour.test(stack);
|
||||
}
|
||||
|
||||
|
|
|
@ -158,60 +158,18 @@ public class AirCurrent {
|
|||
bounds = new AxisAlignedBB(0, 0, 0, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
World world = source.getWorld();
|
||||
BlockPos start = source.getPos();
|
||||
|
||||
direction = source.getBlockState()
|
||||
.get(BlockStateProperties.FACING);
|
||||
pushing = source.getAirFlowDirection() == direction;
|
||||
Vec3d directionVec = new Vec3d(direction.getDirectionVec());
|
||||
Vec3d planeVec = VecHelper.axisAlingedPlaneOf(directionVec);
|
||||
|
||||
// 4 Rays test for holes in the shapes blocking the flow
|
||||
float offsetDistance = .25f;
|
||||
Vec3d[] offsets = new Vec3d[] { planeVec.mul(offsetDistance, offsetDistance, offsetDistance),
|
||||
planeVec.mul(-offsetDistance, -offsetDistance, offsetDistance),
|
||||
planeVec.mul(offsetDistance, -offsetDistance, -offsetDistance),
|
||||
planeVec.mul(-offsetDistance, offsetDistance, -offsetDistance), };
|
||||
|
||||
maxDistance = source.getMaxDistance();
|
||||
float limitedDistance = 0;
|
||||
|
||||
// Determine the distance of the air flow
|
||||
Outer: for (int i = 1; i < maxDistance; i++) {
|
||||
BlockPos currentPos = start.offset(direction, i);
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
break;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (shouldAlwaysPass(state))
|
||||
continue;
|
||||
VoxelShape voxelshape = state.getCollisionShape(world, currentPos, ISelectionContext.dummy());
|
||||
if (voxelshape.isEmpty())
|
||||
continue;
|
||||
if (voxelshape == VoxelShapes.fullCube()) {
|
||||
maxDistance = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (Vec3d offset : offsets) {
|
||||
Vec3d rayStart = VecHelper.getCenterOf(currentPos)
|
||||
.subtract(directionVec.scale(.5f + 1 / 32f))
|
||||
.add(offset);
|
||||
Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
|
||||
BlockRayTraceResult blockraytraceresult =
|
||||
world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, state);
|
||||
if (blockraytraceresult == null)
|
||||
continue Outer;
|
||||
|
||||
double distance = i - 1 + blockraytraceresult.getHitVec()
|
||||
.distanceTo(rayStart);
|
||||
if (limitedDistance < distance)
|
||||
limitedDistance = (float) distance;
|
||||
}
|
||||
|
||||
maxDistance = limitedDistance;
|
||||
break;
|
||||
}
|
||||
World world = source.getWorld();
|
||||
BlockPos start = source.getPos();
|
||||
float max = this.maxDistance;
|
||||
Direction facing = direction;
|
||||
Vec3d directionVec = new Vec3d(facing.getDirectionVec());
|
||||
maxDistance = getFlowLimit(world, start, max, facing);
|
||||
|
||||
// Determine segments with transported fluids/gases
|
||||
AirCurrentSegment currentSegment = new AirCurrentSegment();
|
||||
|
@ -257,6 +215,57 @@ public class AirCurrent {
|
|||
findAffectedHandlers();
|
||||
}
|
||||
|
||||
public static float getFlowLimit(World world, BlockPos start, float max, Direction facing) {
|
||||
Vec3d directionVec = new Vec3d(facing.getDirectionVec());
|
||||
Vec3d planeVec = VecHelper.axisAlingedPlaneOf(directionVec);
|
||||
|
||||
// 4 Rays test for holes in the shapes blocking the flow
|
||||
float offsetDistance = .25f;
|
||||
Vec3d[] offsets = new Vec3d[] { planeVec.mul(offsetDistance, offsetDistance, offsetDistance),
|
||||
planeVec.mul(-offsetDistance, -offsetDistance, offsetDistance),
|
||||
planeVec.mul(offsetDistance, -offsetDistance, -offsetDistance),
|
||||
planeVec.mul(-offsetDistance, offsetDistance, -offsetDistance), };
|
||||
|
||||
float limitedDistance = 0;
|
||||
|
||||
// Determine the distance of the air flow
|
||||
Outer: for (int i = 1; i <= max; i++) {
|
||||
BlockPos currentPos = start.offset(facing, i);
|
||||
if (!world.isBlockPresent(currentPos))
|
||||
break;
|
||||
BlockState state = world.getBlockState(currentPos);
|
||||
if (shouldAlwaysPass(state))
|
||||
continue;
|
||||
VoxelShape voxelshape = state.getCollisionShape(world, currentPos, ISelectionContext.dummy());
|
||||
if (voxelshape.isEmpty())
|
||||
continue;
|
||||
if (voxelshape == VoxelShapes.fullCube()) {
|
||||
max = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
for (Vec3d offset : offsets) {
|
||||
Vec3d rayStart = VecHelper.getCenterOf(currentPos)
|
||||
.subtract(directionVec.scale(.5f + 1 / 32f))
|
||||
.add(offset);
|
||||
Vec3d rayEnd = rayStart.add(directionVec.scale(1 + 1 / 32f));
|
||||
BlockRayTraceResult blockraytraceresult =
|
||||
world.rayTraceBlocks(rayStart, rayEnd, currentPos, voxelshape, state);
|
||||
if (blockraytraceresult == null)
|
||||
continue Outer;
|
||||
|
||||
double distance = i - 1 + blockraytraceresult.getHitVec()
|
||||
.distanceTo(rayStart);
|
||||
if (limitedDistance < distance)
|
||||
limitedDistance = (float) distance;
|
||||
}
|
||||
|
||||
max = limitedDistance;
|
||||
break;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public void findEntities() {
|
||||
caughtEntities.clear();
|
||||
caughtEntities = source.getWorld()
|
||||
|
|
|
@ -16,10 +16,10 @@ public class FluidPipeAttachmentBehaviour extends TileEntityBehaviour {
|
|||
public AttachmentTypes getAttachment(ILightReader world, BlockPos pos, BlockState state, Direction direction) {
|
||||
if (!isPipeConnectedTowards(state, direction))
|
||||
return AttachmentTypes.NONE;
|
||||
|
||||
|
||||
BlockPos offsetPos = pos.offset(direction);
|
||||
BlockState facingState = world.getBlockState(offsetPos);
|
||||
|
||||
|
||||
if (facingState.getBlock() instanceof PumpBlock && facingState.get(PumpBlock.FACING)
|
||||
.getAxis() == direction.getAxis())
|
||||
return AttachmentTypes.NONE;
|
||||
|
@ -31,7 +31,7 @@ public class FluidPipeAttachmentBehaviour extends TileEntityBehaviour {
|
|||
}
|
||||
|
||||
public boolean isPipeConnectedTowards(BlockState state, Direction direction) {
|
||||
FluidPipeBehaviour fluidPipeBehaviour = TileEntityBehaviour.get(tileEntity, FluidPipeBehaviour.TYPE);
|
||||
FluidPipeBehaviour fluidPipeBehaviour = tileEntity.getBehaviour(FluidPipeBehaviour.TYPE);
|
||||
if (fluidPipeBehaviour == null)
|
||||
return false;
|
||||
return fluidPipeBehaviour.isConnectedTo(state, direction);
|
||||
|
|
|
@ -23,7 +23,7 @@ public class TransparentStraightPipeRenderer extends SafeTileEntityRenderer<Stra
|
|||
@Override
|
||||
protected void renderSafe(StraightPipeTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer,
|
||||
int light, int overlay) {
|
||||
FluidPipeBehaviour pipe = TileEntityBehaviour.get(te, FluidPipeBehaviour.TYPE);
|
||||
FluidPipeBehaviour pipe = te.getBehaviour(FluidPipeBehaviour.TYPE);
|
||||
if (pipe == null)
|
||||
return;
|
||||
FluidStack fluidStack = pipe.getFluid();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
|
||||
import com.simibubi.create.content.logistics.InWorldProcessing;
|
||||
import com.simibubi.create.foundation.utility.ColorHelper;
|
||||
|
@ -32,7 +33,7 @@ public class AirFlowParticle extends SimpleAnimatedParticle {
|
|||
this.maxAge = 40;
|
||||
canCollide = false;
|
||||
selectSprite(7);
|
||||
Vec3d offset = VecHelper.offsetRandomly(Vec3d.ZERO, world.rand, .25f);
|
||||
Vec3d offset = VecHelper.offsetRandomly(Vec3d.ZERO, Create.random, .25f);
|
||||
this.setPosition(posX + offset.x, posY + offset.y, posZ + offset.z);
|
||||
this.prevPosX = posX;
|
||||
this.prevPosY = posY;
|
||||
|
|
|
@ -0,0 +1,104 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
import net.minecraft.client.particle.SimpleAnimatedParticle;
|
||||
import net.minecraft.client.renderer.WorldRenderer;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
public class AirParticle extends SimpleAnimatedParticle {
|
||||
|
||||
private float originX, originY, originZ;
|
||||
private float targetX, targetY, targetZ;
|
||||
private float drag;
|
||||
|
||||
private float twirlRadius, twirlAngleOffset;
|
||||
private Axis twirlAxis;
|
||||
|
||||
protected AirParticle(World world, AirParticleData data, double x, double y, double z, double dx, double dy,
|
||||
double dz, IAnimatedSprite sprite) {
|
||||
super(world, x, y, z, sprite, world.rand.nextFloat() * .5f);
|
||||
particleScale *= 0.75F;
|
||||
canCollide = false;
|
||||
|
||||
setPosition(posX, posY, posZ);
|
||||
originX = (float) (prevPosX = posX);
|
||||
originY = (float) (prevPosY = posY);
|
||||
originZ = (float) (prevPosZ = posZ);
|
||||
targetX = (float) (x + dx);
|
||||
targetY = (float) (y + dy);
|
||||
targetZ = (float) (z + dz);
|
||||
drag = data.drag;
|
||||
|
||||
twirlRadius = Create.random.nextFloat() / 6;
|
||||
twirlAngleOffset = Create.random.nextFloat() * 360;
|
||||
twirlAxis = Create.random.nextBoolean() ? Axis.X : Axis.Z;
|
||||
|
||||
// speed in m/ticks
|
||||
maxAge = Math.min((int) (new Vec3d(dx, dy, dz).length() / data.speed), 60);
|
||||
selectSprite(7);
|
||||
setAlphaF(.25f);
|
||||
}
|
||||
|
||||
public IParticleRenderType getRenderType() {
|
||||
return IParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
this.prevPosX = this.posX;
|
||||
this.prevPosY = this.posY;
|
||||
this.prevPosZ = this.posZ;
|
||||
if (this.age++ >= this.maxAge) {
|
||||
this.setExpired();
|
||||
return;
|
||||
}
|
||||
|
||||
float progress = (float) Math.pow(((float) age) / maxAge, drag);
|
||||
float angle = (progress * 2 * 360 + twirlAngleOffset) % 360;
|
||||
Vec3d twirl = VecHelper.rotate(new Vec3d(0, twirlRadius, 0), angle, twirlAxis);
|
||||
|
||||
float x = (float) (MathHelper.lerp(progress, originX, targetX) + twirl.x);
|
||||
float y = (float) (MathHelper.lerp(progress, originY, targetY) + twirl.y);
|
||||
float z = (float) (MathHelper.lerp(progress, originZ, targetZ) + twirl.z);
|
||||
|
||||
motionX = x - posX;
|
||||
motionY = y - posY;
|
||||
motionZ = z - posZ;
|
||||
|
||||
selectSpriteWithAge(field_217584_C);
|
||||
this.move(this.motionX, this.motionY, this.motionZ);
|
||||
}
|
||||
|
||||
public int getBrightnessForRender(float partialTick) {
|
||||
BlockPos blockpos = new BlockPos(this.posX, this.posY, this.posZ);
|
||||
return this.world.isBlockPresent(blockpos) ? WorldRenderer.getLightmapCoordinates(world, blockpos) : 0;
|
||||
}
|
||||
|
||||
private void selectSprite(int index) {
|
||||
setSprite(field_217584_C.get(index, 8));
|
||||
}
|
||||
|
||||
public static class Factory implements IParticleFactory<AirParticleData> {
|
||||
private final IAnimatedSprite spriteSet;
|
||||
|
||||
public Factory(IAnimatedSprite animatedSprite) {
|
||||
this.spriteSet = animatedSprite;
|
||||
}
|
||||
|
||||
public Particle makeParticle(AirParticleData data, World worldIn, double x, double y, double z, double xSpeed,
|
||||
double ySpeed, double zSpeed) {
|
||||
return new AirParticle(worldIn, data, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.mojang.brigadier.StringReader;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.simibubi.create.AllParticleTypes;
|
||||
|
||||
import net.minecraft.client.particle.ParticleManager.IParticleMetaFactory;
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.particles.IParticleData;
|
||||
import net.minecraft.particles.ParticleType;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
public class AirParticleData implements IParticleData, ICustomParticle<AirParticleData> {
|
||||
|
||||
public static final IParticleData.IDeserializer<AirParticleData> DESERIALIZER =
|
||||
new IParticleData.IDeserializer<AirParticleData>() {
|
||||
public AirParticleData deserialize(ParticleType<AirParticleData> particleTypeIn, StringReader reader)
|
||||
throws CommandSyntaxException {
|
||||
reader.expect(' ');
|
||||
float drag = reader.readFloat();
|
||||
reader.expect(' ');
|
||||
float speed = reader.readFloat();
|
||||
return new AirParticleData(drag, speed);
|
||||
}
|
||||
|
||||
public AirParticleData read(ParticleType<AirParticleData> particleTypeIn, PacketBuffer buffer) {
|
||||
return new AirParticleData(buffer.readFloat(), buffer.readFloat());
|
||||
}
|
||||
};
|
||||
|
||||
float drag;
|
||||
float speed;
|
||||
|
||||
public AirParticleData(float drag, float speed) {
|
||||
this.drag = drag;
|
||||
this.speed = speed;
|
||||
}
|
||||
|
||||
public AirParticleData() {
|
||||
this(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParticleType<?> getType() {
|
||||
return AllParticleTypes.AIR.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(PacketBuffer buffer) {
|
||||
buffer.writeFloat(drag);
|
||||
buffer.writeFloat(speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameters() {
|
||||
return String.format(Locale.ROOT, "%s %f %f", AllParticleTypes.AIR.parameter(), drag, speed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IDeserializer<AirParticleData> getDeserializer() {
|
||||
return DESERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public IParticleMetaFactory<AirParticleData> getFactory() {
|
||||
return AirParticle.Factory::new;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,8 +1,11 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import com.mojang.blaze3d.vertex.IVertexBuilder;
|
||||
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
import net.minecraft.client.particle.IParticleRenderType;
|
||||
import net.minecraft.client.particle.Particle;
|
||||
|
@ -15,7 +18,6 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
|
||||
public class CubeParticle extends Particle {
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.simibubi.create.content.contraptions.particle;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
import net.minecraft.client.particle.IAnimatedSprite;
|
||||
import net.minecraft.client.particle.IParticleFactory;
|
||||
|
@ -9,8 +11,6 @@ import net.minecraft.client.particle.SimpleAnimatedParticle;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
public class HeaterParticle extends SimpleAnimatedParticle {
|
||||
|
|
|
@ -360,9 +360,11 @@ public class BeltTileEntity extends KineticTileEntity {
|
|||
private void applyToAllItems(float maxDistanceFromCenter,
|
||||
Function<TransportedItemStack, TransportedResult> processFunction) {
|
||||
BeltTileEntity controller = getControllerTE();
|
||||
if (controller != null)
|
||||
controller.getInventory()
|
||||
.applyToEachWithin(index + .5f, maxDistanceFromCenter, processFunction);
|
||||
if (controller == null)
|
||||
return;
|
||||
BeltInventory inventory = controller.getInventory();
|
||||
if (inventory != null)
|
||||
inventory.applyToEachWithin(index + .5f, maxDistanceFromCenter, processFunction);
|
||||
}
|
||||
|
||||
private Vec3d getWorldPositionOf(TransportedItemStack transported) {
|
||||
|
|
|
@ -3,13 +3,13 @@ package com.simibubi.create.content.contraptions.relays.belt.transport;
|
|||
import com.simibubi.create.content.contraptions.relays.belt.BeltHelper;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.inventory.InvManipulationBehaviour;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.World;
|
||||
|
@ -31,36 +31,38 @@ public class BeltFunnelInteractionHandler {
|
|||
BlockState funnelState = world.getBlockState(funnelPos);
|
||||
if (!(funnelState.getBlock() instanceof BeltFunnelBlock))
|
||||
continue;
|
||||
if (funnelState.get(BeltFunnelBlock.HORIZONTAL_FACING) != beltInventory.belt.getMovementFacing()
|
||||
.getOpposite())
|
||||
Direction funnelFacing = funnelState.get(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||
Direction movementFacing = beltInventory.belt.getMovementFacing();
|
||||
boolean blocking = funnelFacing == movementFacing.getOpposite();
|
||||
if (funnelFacing == movementFacing)
|
||||
continue;
|
||||
|
||||
currentItem.beltPosition = segment + .5f;
|
||||
|
||||
if (world.isRemote)
|
||||
return true;
|
||||
return blocking;
|
||||
if (funnelState.get(BeltFunnelBlock.PUSHING))
|
||||
return true;
|
||||
return blocking;
|
||||
if (funnelState.has(BeltFunnelBlock.POWERED) && funnelState.get(BeltFunnelBlock.POWERED))
|
||||
return true;
|
||||
return blocking;
|
||||
|
||||
TileEntity te = world.getTileEntity(funnelPos);
|
||||
if (!(te instanceof FunnelTileEntity))
|
||||
return true;
|
||||
|
||||
FunnelTileEntity funnelTE = (FunnelTileEntity) te;
|
||||
InvManipulationBehaviour inserting = TileEntityBehaviour.get(funnelTE, InvManipulationBehaviour.TYPE);
|
||||
FilteringBehaviour filtering = TileEntityBehaviour.get(funnelTE, FilteringBehaviour.TYPE);
|
||||
InvManipulationBehaviour inserting = funnelTE.getBehaviour(InvManipulationBehaviour.TYPE);
|
||||
FilteringBehaviour filtering = funnelTE.getBehaviour(FilteringBehaviour.TYPE);
|
||||
|
||||
if (inserting == null)
|
||||
return true;
|
||||
return blocking;
|
||||
if (filtering != null && !filtering.test(currentItem.stack))
|
||||
return true;
|
||||
return blocking;
|
||||
|
||||
ItemStack before = currentItem.stack.copy();
|
||||
ItemStack remainder = inserting.insert(before);
|
||||
if (before.equals(remainder, false))
|
||||
return true;
|
||||
return blocking;
|
||||
|
||||
funnelTE.flap(true);
|
||||
currentItem.stack = remainder;
|
||||
|
|
|
@ -37,8 +37,7 @@ public class BeltTunnelInteractionHandler {
|
|||
if (nextTunnel instanceof BrassTunnelTileEntity) {
|
||||
BrassTunnelTileEntity brassTunnel = (BrassTunnelTileEntity) nextTunnel;
|
||||
if (brassTunnel.hasDistributionBehaviour()) {
|
||||
if (!brassTunnel.getStackToDistribute()
|
||||
.isEmpty())
|
||||
if (!brassTunnel.canTakeItems())
|
||||
return true;
|
||||
if (onServer) {
|
||||
brassTunnel.setStackToDistribute(current.stack);
|
||||
|
|
|
@ -168,10 +168,14 @@ public class BeltTunnelBlock extends Block implements ITE<BeltTunnelTileEntity>,
|
|||
Direction fw = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axis);
|
||||
BlockState blockState1 = reader.getBlockState(pos.offset(fw));
|
||||
BlockState blockState2 = reader.getBlockState(pos.offset(fw.getOpposite()));
|
||||
|
||||
boolean funnel1 = blockState1.getBlock() instanceof BeltFunnelBlock
|
||||
&& blockState1.get(BeltFunnelBlock.SHAPE) == BeltFunnelBlock.Shape.EXTENDED
|
||||
&& blockState1.get(BeltFunnelBlock.HORIZONTAL_FACING) == fw.getOpposite();
|
||||
boolean funnel2 = blockState2.getBlock() instanceof BeltFunnelBlock
|
||||
&& blockState2.get(BeltFunnelBlock.SHAPE) == BeltFunnelBlock.Shape.EXTENDED
|
||||
&& blockState2.get(BeltFunnelBlock.HORIZONTAL_FACING) == fw;
|
||||
|
||||
boolean valid1 = blockState1.getBlock() instanceof BeltTunnelBlock || funnel1;
|
||||
boolean valid2 = blockState2.getBlock() instanceof BeltTunnelBlock || funnel2;
|
||||
boolean canHaveWindow = valid1 && valid2 && !(funnel1 && funnel2);
|
||||
|
|
|
@ -130,7 +130,8 @@ public class BeltTunnelTileEntity extends SmartTileEntity {
|
|||
|
||||
BlockState funnelState = world.getBlockState(getPos().offset(direction));
|
||||
if (funnelState.getBlock() instanceof BeltFunnelBlock)
|
||||
if (funnelState.get(BeltFunnelBlock.HORIZONTAL_FACING) == direction.getOpposite())
|
||||
if (funnelState.get(BeltFunnelBlock.SHAPE) == BeltFunnelBlock.Shape.EXTENDED
|
||||
&& funnelState.get(BeltFunnelBlock.HORIZONTAL_FACING) == direction.getOpposite())
|
||||
continue;
|
||||
|
||||
flaps.put(direction, new InterpolatedChasingValue().start(.25f)
|
||||
|
|
|
@ -31,7 +31,7 @@ public class BrassTunnelItemHandler implements IItemHandler {
|
|||
return beltCapability.orElse(null).insertItem(slot, stack, simulate);
|
||||
}
|
||||
|
||||
if (!te.stackToDistribute.isEmpty())
|
||||
if (!te.canTakeItems())
|
||||
return stack;
|
||||
if (!simulate)
|
||||
te.setStackToDistribute(stack);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
package com.simibubi.create.content.logistics.block.belts.tunnel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
|
@ -58,6 +60,9 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
int distributionDistanceRight;
|
||||
int previousOutputIndex;
|
||||
|
||||
private boolean syncedOutputActive;
|
||||
private Set<BrassTunnelTileEntity> syncSet;
|
||||
|
||||
protected ScrollOptionBehaviour<SelectionMode> selectionMode;
|
||||
private LazyOptional<IItemHandler> beltCapability;
|
||||
private LazyOptional<IItemHandler> tunnelCapability;
|
||||
|
@ -65,10 +70,12 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
public BrassTunnelTileEntity(TileEntityType<? extends BeltTunnelTileEntity> type) {
|
||||
super(type);
|
||||
distributionTargets = new ArrayList<>();
|
||||
syncSet = new HashSet<>();
|
||||
stackToDistribute = ItemStack.EMPTY;
|
||||
beltCapability = LazyOptional.empty();
|
||||
tunnelCapability = LazyOptional.of(() -> new BrassTunnelItemHandler(this));
|
||||
previousOutputIndex = 0;
|
||||
syncedOutputActive = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,7 +107,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
distributionProgress--;
|
||||
if (beltBelow == null || beltBelow.getSpeed() == 0)
|
||||
return;
|
||||
if (stackToDistribute.isEmpty())
|
||||
if (stackToDistribute.isEmpty() && !syncedOutputActive)
|
||||
return;
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
@ -109,7 +116,28 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
distributionTargets.clear();
|
||||
distributionDistanceLeft = 0;
|
||||
distributionDistanceRight = 0;
|
||||
for (Pair<BrassTunnelTileEntity, Direction> pair : gatherValidOutputs()) {
|
||||
|
||||
syncSet.clear();
|
||||
List<Pair<BrassTunnelTileEntity, Direction>> validOutputs = gatherValidOutputs();
|
||||
if (selectionMode.get() == SelectionMode.SYNCHRONIZE) {
|
||||
boolean allEmpty = true;
|
||||
boolean allFull = true;
|
||||
for (BrassTunnelTileEntity te : syncSet) {
|
||||
boolean hasStack = !te.stackToDistribute.isEmpty();
|
||||
allEmpty &= !hasStack;
|
||||
allFull &= hasStack;
|
||||
}
|
||||
final boolean notifySyncedOut = !allEmpty;
|
||||
if (allFull || allEmpty)
|
||||
syncSet.forEach(te -> te.syncedOutputActive = notifySyncedOut);
|
||||
}
|
||||
|
||||
if (validOutputs == null)
|
||||
return;
|
||||
if (stackToDistribute.isEmpty())
|
||||
return;
|
||||
|
||||
for (Pair<BrassTunnelTileEntity, Direction> pair : validOutputs) {
|
||||
BrassTunnelTileEntity tunnel = pair.getKey();
|
||||
Direction output = pair.getValue();
|
||||
if (insertIntoTunnel(tunnel, output, stackToDistribute, true) == null)
|
||||
|
@ -125,8 +153,10 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
if (distributionTargets.isEmpty())
|
||||
return;
|
||||
|
||||
distributionProgress = 10;
|
||||
sendData();
|
||||
if (selectionMode.get() != SelectionMode.SYNCHRONIZE || syncedOutputActive) {
|
||||
distributionProgress = 10;
|
||||
sendData();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -162,7 +192,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
|
||||
if (mode == SelectionMode.RANDOMIZE)
|
||||
indexStart = rand.nextInt(amountTargets);
|
||||
if (mode == SelectionMode.PREFER_NEAREST)
|
||||
if (mode == SelectionMode.PREFER_NEAREST || mode == SelectionMode.SYNCHRONIZE)
|
||||
indexStart = 0;
|
||||
|
||||
ItemStack toDistribute = null;
|
||||
|
@ -290,7 +320,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
public void initialize() {
|
||||
if (filtering == null) {
|
||||
filtering = createSidedFilter();
|
||||
putBehaviour(filtering);
|
||||
attachBehaviourLate(filtering);
|
||||
}
|
||||
super.initialize();
|
||||
}
|
||||
|
@ -322,22 +352,29 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
|
||||
private List<Pair<BrassTunnelTileEntity, Direction>> gatherValidOutputs() {
|
||||
List<Pair<BrassTunnelTileEntity, Direction>> validOutputs = new ArrayList<>();
|
||||
boolean synchronize = selectionMode.get() == SelectionMode.SYNCHRONIZE;
|
||||
addValidOutputsOf(this, validOutputs);
|
||||
|
||||
for (boolean left : Iterate.trueAndFalse) {
|
||||
BrassTunnelTileEntity adjacent = this;
|
||||
while (adjacent != null) {
|
||||
if (!world.isAreaLoaded(adjacent.getPos(), 1))
|
||||
return null;
|
||||
adjacent = adjacent.getAdjacent(left);
|
||||
if (adjacent != null)
|
||||
addValidOutputsOf(adjacent, validOutputs);
|
||||
if (adjacent == null)
|
||||
continue;
|
||||
addValidOutputsOf(adjacent, validOutputs);
|
||||
}
|
||||
}
|
||||
|
||||
if (!syncedOutputActive && synchronize)
|
||||
return null;
|
||||
return validOutputs;
|
||||
}
|
||||
|
||||
private void addValidOutputsOf(BrassTunnelTileEntity tunnelTE,
|
||||
List<Pair<BrassTunnelTileEntity, Direction>> validOutputs) {
|
||||
syncSet.add(tunnelTE);
|
||||
BeltTileEntity below = BeltHelper.getSegmentTE(world, tunnelTE.pos.down());
|
||||
if (below == null)
|
||||
return;
|
||||
|
@ -400,6 +437,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
|
||||
@Override
|
||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
compound.putBoolean("SyncedOutput", syncedOutputActive);
|
||||
compound.putBoolean("ConnectedLeft", connectedLeft);
|
||||
compound.putBoolean("ConnectedRight", connectedRight);
|
||||
|
||||
|
@ -424,6 +462,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
boolean wasConnectedLeft = connectedLeft;
|
||||
boolean wasConnectedRight = connectedRight;
|
||||
|
||||
syncedOutputActive = compound.getBoolean("SyncedOutput");
|
||||
connectedLeft = compound.getBoolean("ConnectedLeft");
|
||||
connectedRight = compound.getBoolean("ConnectedRight");
|
||||
stackToDistribute = ItemStack.read(compound.getCompound("StackToDistribute"));
|
||||
|
@ -549,6 +588,7 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
FORCED_ROUND_ROBIN(AllIcons.I_TUNNEL_FORCED_ROUND_ROBIN),
|
||||
PREFER_NEAREST(AllIcons.I_TUNNEL_PREFER_NEAREST),
|
||||
RANDOMIZE(AllIcons.I_TUNNEL_RANDOMIZE),
|
||||
SYNCHRONIZE(AllIcons.I_TUNNEL_SYNCHRONIZE),
|
||||
|
||||
;
|
||||
|
||||
|
@ -571,4 +611,8 @@ public class BrassTunnelTileEntity extends BeltTunnelTileEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean canTakeItems() {
|
||||
return stackToDistribute.isEmpty() && !syncedOutputActive;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -147,6 +147,13 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
|
|||
return updateDiagonalState(state, above, world, pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void neighborChanged(BlockState p_220069_1_, World world, BlockPos pos, Block p_220069_4_,
|
||||
BlockPos neighbourPos, boolean p_220069_6_) {
|
||||
if (pos.down().equals(neighbourPos))
|
||||
withTileEntityDo(world, pos, ChuteTileEntity::blockBelowChanged);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidPosition(BlockState state, IWorldReader world, BlockPos pos) {
|
||||
BlockState above = world.getBlockState(pos.up());
|
||||
|
@ -226,7 +233,7 @@ public class ChuteBlock extends Block implements IWrenchable, ITE<ChuteTileEntit
|
|||
ISelectionContext p_220053_4_) {
|
||||
return ChuteShapes.getShape(p_220053_1_);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public boolean addDestroyEffects(BlockState state, World world, BlockPos pos, ParticleManager manager) {
|
||||
|
|
|
@ -27,7 +27,8 @@ public class ChuteRenderer extends SafeTileEntityRenderer<ChuteTileEntity> {
|
|||
BlockState blockState = te.getBlockState();
|
||||
if (blockState.get(ChuteBlock.FACING) != Direction.DOWN)
|
||||
return;
|
||||
if (blockState.get(ChuteBlock.SHAPE) != Shape.WINDOW)
|
||||
if (blockState.get(ChuteBlock.SHAPE) != Shape.WINDOW
|
||||
&& (te.bottomPullDistance == 0 || te.itemPosition.get(partialTicks) > .5f))
|
||||
return;
|
||||
|
||||
ItemRenderer itemRenderer = Minecraft.getInstance()
|
||||
|
|
|
@ -7,18 +7,25 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.content.contraptions.components.fan.AirCurrent;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanBlock;
|
||||
import com.simibubi.create.content.contraptions.components.fan.EncasedFanTileEntity;
|
||||
import com.simibubi.create.content.contraptions.goggles.IHaveGoggleInformation;
|
||||
import com.simibubi.create.content.contraptions.particle.AirParticleData;
|
||||
import com.simibubi.create.content.logistics.block.chute.ChuteBlock.Shape;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BrassFunnelBlock;
|
||||
import com.simibubi.create.content.logistics.block.funnel.FunnelBlock;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedValue;
|
||||
import com.simibubi.create.foundation.item.ItemHelper;
|
||||
import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour;
|
||||
import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour.TransportedResult;
|
||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
import com.simibubi.create.foundation.utility.VecHelper;
|
||||
|
||||
|
@ -33,6 +40,7 @@ import net.minecraft.particles.ParticleTypes;
|
|||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityType;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.AxisAlignedBB;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
@ -54,6 +62,13 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
LazyOptional<IItemHandler> lazyHandler;
|
||||
boolean canPickUpItems;
|
||||
|
||||
float bottomPullDistance;
|
||||
int airCurrentUpdateCooldown;
|
||||
int entitySearchCooldown;
|
||||
boolean updateAirFlow;
|
||||
TransportedItemStackHandlerBehaviour beltBelow;
|
||||
float beltBelowOffset;
|
||||
|
||||
LazyOptional<IItemHandler> capAbove;
|
||||
LazyOptional<IItemHandler> capBelow;
|
||||
|
||||
|
@ -66,6 +81,8 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
canPickUpItems = false;
|
||||
capAbove = LazyOptional.empty();
|
||||
capBelow = LazyOptional.empty();
|
||||
bottomPullDistance = 0;
|
||||
updateAirFlow = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,14 +111,25 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
@Override
|
||||
public void initialize() {
|
||||
super.initialize();
|
||||
onAdded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisAlignedBB getRenderBoundingBox() {
|
||||
return new AxisAlignedBB(pos).expand(0, -3, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
|
||||
canPickUpItems = canDirectlyInsert();
|
||||
|
||||
float itemMotion = getItemMotion();
|
||||
if (itemMotion != 0 && world.isRemote)
|
||||
spawnParticles(itemMotion);
|
||||
if (itemMotion > 0)
|
||||
tickAirStreamFromBelow(itemMotion);
|
||||
|
||||
if (item.isEmpty()) {
|
||||
if (itemMotion < 0)
|
||||
|
@ -138,6 +166,127 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
itemPosition.set(nextOffset);
|
||||
}
|
||||
|
||||
private void tickAirStreamFromBelow(float itemSpeed) {
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
if (airCurrentUpdateCooldown-- <= 0) {
|
||||
airCurrentUpdateCooldown = AllConfigs.SERVER.kinetics.fanBlockCheckRate.get();
|
||||
updateAirFlow = true;
|
||||
}
|
||||
|
||||
if (bottomPullDistance > 0 && getItem().isEmpty() && entitySearchCooldown-- <= 0) {
|
||||
entitySearchCooldown = 5;
|
||||
Vec3d center = VecHelper.getCenterOf(pos);
|
||||
AxisAlignedBB searchArea =
|
||||
new AxisAlignedBB(center.add(0, -bottomPullDistance - 0.5, 0), center.add(0, -0.5, 0)).grow(.45f);
|
||||
for (ItemEntity itemEntity : world.getEntitiesWithinAABB(ItemEntity.class, searchArea)) {
|
||||
setItem(itemEntity.getItem()
|
||||
.copy(),
|
||||
(float) (itemEntity.getBoundingBox()
|
||||
.getCenter().y - pos.getY()));
|
||||
itemEntity.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (getItem().isEmpty() && beltBelow != null) {
|
||||
beltBelow.handleCenteredProcessingOnAllItems(.5f, ts -> {
|
||||
if (getItem().isEmpty()) {
|
||||
setItem(ts.stack.copy(), -beltBelowOffset);
|
||||
return TransportedResult.removeItem();
|
||||
}
|
||||
return TransportedResult.doNothing();
|
||||
});
|
||||
}
|
||||
|
||||
if (!updateAirFlow)
|
||||
return;
|
||||
|
||||
float speed = pull - push;
|
||||
float flowLimit = 0;
|
||||
updateAirFlow = false;
|
||||
beltBelow = null;
|
||||
|
||||
float maxPullDistance;
|
||||
if (speed >= 128)
|
||||
maxPullDistance = 3;
|
||||
else if (speed >= 64)
|
||||
maxPullDistance = 2;
|
||||
else if (speed >= 32)
|
||||
maxPullDistance = 1;
|
||||
else
|
||||
maxPullDistance = MathHelper.lerp(speed / 32, 0, 1);
|
||||
|
||||
if (AllBlocks.CHUTE.has(world.getBlockState(pos.down())))
|
||||
maxPullDistance = 0;
|
||||
flowLimit = maxPullDistance;
|
||||
if (flowLimit > 0)
|
||||
flowLimit = AirCurrent.getFlowLimit(world, pos, maxPullDistance, Direction.DOWN);
|
||||
|
||||
for (int i = 1; i <= flowLimit + 1; i++) {
|
||||
TransportedItemStackHandlerBehaviour behaviour =
|
||||
TileEntityBehaviour.get(world, pos.down(i), TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
continue;
|
||||
beltBelow = behaviour;
|
||||
beltBelowOffset = i - 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bottomPullDistance == flowLimit)
|
||||
return;
|
||||
|
||||
this.bottomPullDistance = flowLimit;
|
||||
sendData();
|
||||
}
|
||||
|
||||
public void blockBelowChanged() {
|
||||
updateAirFlow = true;
|
||||
}
|
||||
|
||||
private void spawnParticles(float itemMotion) {
|
||||
BlockState blockState = getBlockState();
|
||||
boolean up = itemMotion > 0;
|
||||
float absMotion = up ? itemMotion : -itemMotion;
|
||||
if (blockState == null || !(blockState.getBlock() instanceof ChuteBlock))
|
||||
return;
|
||||
if (push == 0 && pull == 0)
|
||||
return;
|
||||
|
||||
if (up
|
||||
&& (blockState.get(ChuteBlock.FACING) == Direction.DOWN
|
||||
|| blockState.get(ChuteBlock.SHAPE) == Shape.INTERSECTION)
|
||||
&& BlockHelper.noCollisionInSpace(world, pos.up()))
|
||||
spawnAirFlow(1, 2, absMotion, .5f);
|
||||
|
||||
if (blockState.get(ChuteBlock.FACING) != Direction.DOWN)
|
||||
return;
|
||||
|
||||
if (blockState.get(ChuteBlock.SHAPE) == Shape.WINDOW)
|
||||
spawnAirFlow(up ? 0 : 1, up ? 1 : 0, absMotion, 1);
|
||||
|
||||
if (!up && BlockHelper.noCollisionInSpace(world, pos.down()))
|
||||
spawnAirFlow(0, -1, absMotion, .5f);
|
||||
|
||||
if (up && bottomPullDistance > 0) {
|
||||
spawnAirFlow(-bottomPullDistance, 0, absMotion, 2);
|
||||
spawnAirFlow(-bottomPullDistance, 0, absMotion, 2);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnAirFlow(float verticalStart, float verticalEnd, float motion, float drag) {
|
||||
AirParticleData airParticleData = new AirParticleData(drag, motion);
|
||||
Vec3d origin = new Vec3d(pos);
|
||||
float xOff = Create.random.nextFloat() * .5f + .25f;
|
||||
float zOff = Create.random.nextFloat() * .5f + .25f;
|
||||
Vec3d v = origin.add(xOff, verticalStart, zOff);
|
||||
Vec3d d = origin.add(xOff, verticalEnd, zOff)
|
||||
.subtract(v);
|
||||
if (Create.random.nextFloat() < 2 * motion)
|
||||
world.addOptionalParticle(airParticleData, v.x, v.y, v.z, d.x, d.y, d.z);
|
||||
}
|
||||
|
||||
private void handleInputFromAbove() {
|
||||
if (!capAbove.isPresent())
|
||||
capAbove = grabCapability(Direction.UP);
|
||||
|
@ -200,7 +349,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
capBelow = grabCapability(Direction.DOWN);
|
||||
if (capBelow.isPresent()) {
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capBelow.orElse(null), item, simulate);
|
||||
if (!simulate)
|
||||
if (!simulate)
|
||||
setItem(ItemStack.EMPTY);
|
||||
return remainder.isEmpty();
|
||||
}
|
||||
|
@ -260,7 +409,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
capAbove = grabCapability(Direction.UP);
|
||||
if (capAbove.isPresent()) {
|
||||
ItemStack remainder = ItemHandlerHelper.insertItemStacked(capAbove.orElse(null), item, simulate);
|
||||
if (!simulate)
|
||||
if (!simulate)
|
||||
setItem(ItemStack.EMPTY);
|
||||
return remainder.isEmpty();
|
||||
}
|
||||
|
@ -314,6 +463,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
compound.putFloat("ItemPosition", itemPosition.value);
|
||||
compound.putFloat("Pull", pull);
|
||||
compound.putFloat("Push", push);
|
||||
compound.putFloat("BottomAirFlowDistance", bottomPullDistance);
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
||||
|
@ -324,6 +474,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
itemPosition.lastValue = itemPosition.value = compound.getFloat("ItemPosition");
|
||||
pull = compound.getFloat("Pull");
|
||||
push = compound.getFloat("Push");
|
||||
bottomPullDistance = compound.getFloat("BottomAirFlowDistance");
|
||||
super.read(compound, clientPacket);
|
||||
|
||||
if (hasWorld() && world.isRemote && !previousItem.equals(item, false) && !item.isEmpty()) {
|
||||
|
@ -339,11 +490,11 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
public float getItemMotion() {
|
||||
// Chutes per second
|
||||
final float fanSpeedModifier = 1 / 64f;
|
||||
final float maxUpwardItemSpeed = 20f;
|
||||
final float maxItemSpeed = 20f;
|
||||
final float gravity = 4f;
|
||||
|
||||
float upwardMotion = (push + pull) * fanSpeedModifier;
|
||||
return (upwardMotion == 0 ? -gravity : MathHelper.clamp(upwardMotion, 0, maxUpwardItemSpeed)) / 20f;
|
||||
float motion = (push + pull) * fanSpeedModifier;
|
||||
return (MathHelper.clamp(motion, -maxItemSpeed, maxItemSpeed) + (motion <= 0 ? -gravity : 0)) / 20f;
|
||||
}
|
||||
|
||||
public void onRemoved(BlockState chuteState) {
|
||||
|
@ -374,6 +525,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
if (pull == totalPull)
|
||||
return;
|
||||
pull = totalPull;
|
||||
updateAirFlow = true;
|
||||
sendData();
|
||||
ChuteTileEntity targetChute = getTargetChute(getBlockState());
|
||||
if (targetChute != null)
|
||||
|
@ -384,6 +536,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
float totalPush = calculatePush(branchCount);
|
||||
if (push == totalPush)
|
||||
return;
|
||||
updateAirFlow = true;
|
||||
push = totalPush;
|
||||
sendData();
|
||||
propagatePush();
|
||||
|
@ -401,7 +554,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
TileEntity te = world.getTileEntity(pos.up());
|
||||
if (te instanceof EncasedFanTileEntity && !te.isRemoved()) {
|
||||
EncasedFanTileEntity fan = (EncasedFanTileEntity) te;
|
||||
return Math.abs(fan.getSpeed());
|
||||
return fan.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +574,7 @@ public class ChuteTileEntity extends SmartTileEntity implements IHaveGoggleInfor
|
|||
TileEntity te = world.getTileEntity(pos.down());
|
||||
if (te instanceof EncasedFanTileEntity && !te.isRemoved()) {
|
||||
EncasedFanTileEntity fan = (EncasedFanTileEntity) te;
|
||||
return Math.abs(fan.getSpeed());
|
||||
return fan.getSpeed();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,13 +95,10 @@ public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
|
|||
boolean renderUpright = BeltHelper.isItemUpright(itemStack);
|
||||
boolean blockItem = itemRenderer.getItemModelWithOverrides(itemStack, null, null)
|
||||
.isGui3d();
|
||||
|
||||
|
||||
ms.push();
|
||||
msr.rotateY(angle);
|
||||
if (!blockItem && !renderUpright) {
|
||||
ms.translate(0, -.09375, 0);
|
||||
msr.rotateX(90);
|
||||
}
|
||||
|
||||
if (renderUpright) {
|
||||
Entity renderViewEntity = Minecraft.getInstance().renderViewEntity;
|
||||
if (renderViewEntity != null) {
|
||||
|
@ -111,14 +108,18 @@ public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
|
|||
float yRot = (float) MathHelper.atan2(diff.z, -diff.x);
|
||||
ms.multiply(Vector3f.POSITIVE_Y.getRadialQuaternion((float) (yRot - Math.PI / 2)));
|
||||
}
|
||||
ms.translate(0, 3 / 32d, 1/16f);
|
||||
ms.translate(0, 3 / 32d, 1 / 16f);
|
||||
}
|
||||
|
||||
|
||||
for (int i = 0; i <= count; i++) {
|
||||
ms.push();
|
||||
if (blockItem)
|
||||
ms.translate(r.nextFloat() * .0625f * i, 0, r.nextFloat() * .0625f * i);
|
||||
ms.scale(.5f, .5f, .5f);
|
||||
if (!blockItem && !renderUpright) {
|
||||
ms.translate(0, -3 / 16f, 0);
|
||||
msr.rotateX(90);
|
||||
}
|
||||
itemRenderer.renderItem(itemStack, TransformType.FIXED, light, overlay, ms, buffer);
|
||||
ms.pop();
|
||||
|
||||
|
@ -129,7 +130,7 @@ public class DepotRenderer extends SafeTileEntityRenderer<DepotTileEntity> {
|
|||
} else
|
||||
ms.translate(0, 0, -1 / 16f);
|
||||
}
|
||||
|
||||
|
||||
ms.pop();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ public class DepotTileEntity extends SmartTileEntity {
|
|||
|
||||
DepotItemHandler itemHandler;
|
||||
LazyOptional<DepotItemHandler> lazyItemHandler;
|
||||
private TransportedItemStackHandlerBehaviour transportedHandler;
|
||||
|
||||
public DepotTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
|
@ -75,9 +76,8 @@ public class DepotTileEntity extends SmartTileEntity {
|
|||
|
||||
boolean wasLocked = heldItem.locked;
|
||||
ItemStack previousItem = heldItem.stack;
|
||||
TransportedItemStackHandlerBehaviour handler = getBehaviour(TransportedItemStackHandlerBehaviour.TYPE);
|
||||
ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, handler)
|
||||
: processingBehaviour.handleReceivedItem(heldItem, handler);
|
||||
ProcessingResult result = wasLocked ? processingBehaviour.handleHeldItem(heldItem, transportedHandler)
|
||||
: processingBehaviour.handleReceivedItem(heldItem, transportedHandler);
|
||||
if (result == ProcessingResult.REMOVE) {
|
||||
heldItem = null;
|
||||
sendData();
|
||||
|
@ -116,8 +116,9 @@ public class DepotTileEntity extends SmartTileEntity {
|
|||
@Override
|
||||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).setInsertionHandler(this::tryInsertingFromSide));
|
||||
behaviours.add(new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf));
|
||||
transportedHandler = new TransportedItemStackHandlerBehaviour(this, this::applyToAllItems)
|
||||
.withStackPlacement(this::getWorldPositionOf);
|
||||
behaviours.add(transportedHandler);
|
||||
}
|
||||
|
||||
public ItemStack getHeldItemStack() {
|
||||
|
|
|
@ -101,16 +101,19 @@ public abstract class BeltFunnelBlock extends HorizontalInteractionFunnelBlock {
|
|||
return false;
|
||||
if (!BeltBlock.canTransport(stateBelow))
|
||||
return false;
|
||||
if (stateBelow.get(BeltBlock.HORIZONTAL_FACING)
|
||||
.getAxis() != state.get(HORIZONTAL_FACING)
|
||||
.getAxis())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public static BlockState updateShape(BlockState state, IBlockReader world, BlockPos pos) {
|
||||
state = state.with(SHAPE, Shape.RETRACTED);
|
||||
BlockState neighbour = world.getBlockState(pos.offset(state.get(HORIZONTAL_FACING)));
|
||||
Direction horizontalFacing = state.get(HORIZONTAL_FACING);
|
||||
|
||||
BlockState below = world.getBlockState(pos.down());
|
||||
if (below.getBlock() instanceof BeltBlock && below.get(BeltBlock.HORIZONTAL_FACING)
|
||||
.getAxis() != horizontalFacing.getAxis())
|
||||
return state;
|
||||
|
||||
BlockState neighbour = world.getBlockState(pos.offset(horizontalFacing));
|
||||
if (canConnectTo(state, neighbour))
|
||||
return state.with(SHAPE, Shape.EXTENDED);
|
||||
return state;
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
package com.simibubi.create.content.logistics.block.funnel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.simibubi.create.AllBlocks;
|
||||
import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack;
|
||||
import com.simibubi.create.content.logistics.block.funnel.BeltFunnelBlock.Shape;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedChasingValue;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -26,16 +29,19 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
|
||||
private FilteringBehaviour filtering;
|
||||
private InvManipulationBehaviour invManipulation;
|
||||
private InvManipulationBehaviour autoExtractor;
|
||||
private int extractionCooldown;
|
||||
|
||||
int sendFlap;
|
||||
InterpolatedChasingValue flap;
|
||||
|
||||
static enum Mode {
|
||||
INVALID, PAUSED, COLLECT, BELT
|
||||
INVALID, PAUSED, COLLECT, PUSHING_TO_BELT, TAKING_FROM_BELT, HOPPER
|
||||
}
|
||||
|
||||
public FunnelTileEntity(TileEntityType<?> tileEntityTypeIn) {
|
||||
super(tileEntityTypeIn);
|
||||
extractionCooldown = 0;
|
||||
flap = new InterpolatedChasingValue().start(.25f)
|
||||
.target(0)
|
||||
.withSpeed(.05f);
|
||||
|
@ -47,8 +53,12 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
return Mode.INVALID;
|
||||
if (state.has(BlockStateProperties.POWERED) && state.get(BlockStateProperties.POWERED))
|
||||
return Mode.PAUSED;
|
||||
if (state.getBlock() instanceof BeltFunnelBlock)
|
||||
return Mode.BELT;
|
||||
if (FunnelBlock.getFunnelFacing(state) == Direction.UP && autoExtractor.hasInventory())
|
||||
return Mode.HOPPER;
|
||||
if (state.getBlock() instanceof BeltFunnelBlock) {
|
||||
boolean pushing = state.get(BeltFunnelBlock.PUSHING);
|
||||
return pushing ? Mode.PUSHING_TO_BELT : Mode.TAKING_FROM_BELT;
|
||||
}
|
||||
return Mode.COLLECT;
|
||||
}
|
||||
|
||||
|
@ -57,45 +67,87 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
super.tick();
|
||||
flap.tick();
|
||||
Mode mode = determineCurrentMode();
|
||||
if (mode == Mode.BELT)
|
||||
tickAsBeltFunnel();
|
||||
if (world.isRemote)
|
||||
return;
|
||||
}
|
||||
|
||||
public void tickAsBeltFunnel() {
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = blockState.get(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
Boolean pushing = blockState.get(BeltFunnelBlock.PUSHING);
|
||||
if (!pushing) {
|
||||
// Belts handle insertion from their side
|
||||
if (AllBlocks.BELT.has(world.getBlockState(pos.down())))
|
||||
return;
|
||||
TransportedItemStackHandlerBehaviour handler =
|
||||
TileEntityBehaviour.get(world, pos.down(), TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (handler == null)
|
||||
return;
|
||||
handler.handleCenteredProcessingOnAllItems(1 / 32f, this::collectFromHandler);
|
||||
// Redstone resets the extraction cooldown
|
||||
if (mode == Mode.PAUSED)
|
||||
extractionCooldown = 0;
|
||||
if (mode == Mode.TAKING_FROM_BELT)
|
||||
tickAsPullingBeltFunnel();
|
||||
|
||||
if (extractionCooldown > 0) {
|
||||
extractionCooldown--;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode == Mode.PUSHING_TO_BELT)
|
||||
activateExtractingBeltFunnel();
|
||||
if (mode == Mode.HOPPER)
|
||||
activateHopper();
|
||||
}
|
||||
|
||||
private void activateHopper() {
|
||||
if (!invManipulation.hasInventory())
|
||||
return;
|
||||
int amountToExtract = autoExtractor.getAmountFromFilter();
|
||||
if (!filtering.isActive())
|
||||
amountToExtract = 1;
|
||||
|
||||
Predicate<ItemStack> filter = s -> !filtering.isActive() || filtering.test(s);
|
||||
Function<ItemStack, Integer> amountThreshold = s -> s.getMaxStackSize() - invManipulation.simulate()
|
||||
.insert(s)
|
||||
.getCount();
|
||||
|
||||
if (amountToExtract != -1 && !invManipulation.simulate()
|
||||
.insert(autoExtractor.simulate()
|
||||
.extract(amountToExtract, filter))
|
||||
.isEmpty())
|
||||
return;
|
||||
|
||||
ItemStack stack = autoExtractor.extract(amountToExtract, filter, amountThreshold);
|
||||
if (stack.isEmpty())
|
||||
return;
|
||||
invManipulation.insert(stack);
|
||||
startCooldown();
|
||||
}
|
||||
|
||||
private void tickAsPullingBeltFunnel() {
|
||||
// Belts handle insertion from their side
|
||||
if (AllBlocks.BELT.has(world.getBlockState(pos.down())))
|
||||
return;
|
||||
TransportedItemStackHandlerBehaviour handler =
|
||||
TileEntityBehaviour.get(world, pos.down(), TransportedItemStackHandlerBehaviour.TYPE);
|
||||
if (handler == null)
|
||||
return;
|
||||
handler.handleCenteredProcessingOnAllItems(1 / 32f, this::collectFromHandler);
|
||||
}
|
||||
|
||||
private void activateExtractingBeltFunnel() {
|
||||
BlockState blockState = getBlockState();
|
||||
Direction facing = blockState.get(BeltFunnelBlock.HORIZONTAL_FACING);
|
||||
DirectBeltInputBehaviour inputBehaviour =
|
||||
TileEntityBehaviour.get(world, pos.down(), DirectBeltInputBehaviour.TYPE);
|
||||
|
||||
if (inputBehaviour == null)
|
||||
return;
|
||||
if (!inputBehaviour.canInsertFromSide(facing))
|
||||
return;
|
||||
|
||||
ItemStack stack = invManipulation.extract(invManipulation.getAmountFromFilter(),
|
||||
s -> inputBehaviour.handleInsertion(s, facing, true)
|
||||
.isEmpty());
|
||||
int amountToExtract = invManipulation.getAmountFromFilter();
|
||||
if (!filtering.isActive())
|
||||
amountToExtract = 1;
|
||||
ItemStack stack = invManipulation.extract(amountToExtract, s -> inputBehaviour.handleInsertion(s, facing, true)
|
||||
.isEmpty());
|
||||
if (stack.isEmpty())
|
||||
return;
|
||||
flap(false);
|
||||
inputBehaviour.handleInsertion(stack, facing, false);
|
||||
startCooldown();
|
||||
}
|
||||
|
||||
private int startCooldown() {
|
||||
return extractionCooldown = AllConfigs.SERVER.logistics.defaultExtractionTimer.get();
|
||||
}
|
||||
|
||||
private TransportedResult collectFromHandler(TransportedItemStack stack) {
|
||||
|
@ -120,18 +172,27 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
public void addBehaviours(List<TileEntityBehaviour> behaviours) {
|
||||
invManipulation = new InvManipulationBehaviour(this, InterfaceProvider.oppositeOfBlockFacing());
|
||||
behaviours.add(invManipulation);
|
||||
autoExtractor = InvManipulationBehaviour.forExtraction(this, InterfaceProvider.towardBlockFacing());
|
||||
behaviours.add(autoExtractor);
|
||||
|
||||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning()).showCountWhen(() -> {
|
||||
BlockState blockState = getBlockState();
|
||||
return blockState.getBlock() instanceof HorizontalInteractionFunnelBlock
|
||||
&& blockState.get(HorizontalInteractionFunnelBlock.PUSHING);
|
||||
});
|
||||
filtering = new FilteringBehaviour(this, new FunnelFilterSlotPositioning());
|
||||
filtering.showCountWhen(this::supportsAmountOnFilter);
|
||||
filtering.onlyActiveWhen(this::supportsFiltering);
|
||||
behaviours.add(filtering);
|
||||
|
||||
behaviours.add(new DirectBeltInputBehaviour(this).onlyInsertWhen(this::supportsDirectBeltInput)
|
||||
.setInsertionHandler(this::handleDirectBeltInput));
|
||||
}
|
||||
|
||||
private boolean supportsAmountOnFilter() {
|
||||
BlockState blockState = getBlockState();
|
||||
boolean pushingToBelt = blockState.getBlock() instanceof HorizontalInteractionFunnelBlock
|
||||
&& blockState.get(HorizontalInteractionFunnelBlock.PUSHING);
|
||||
boolean hopper = FunnelBlock.getFunnelFacing(blockState) == Direction.UP && invManipulation.hasInventory()
|
||||
&& autoExtractor.hasInventory();
|
||||
return pushingToBelt || hopper;
|
||||
}
|
||||
|
||||
private boolean supportsDirectBeltInput(Direction side) {
|
||||
BlockState blockState = getBlockState();
|
||||
if (blockState == null)
|
||||
|
@ -171,6 +232,7 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
@Override
|
||||
protected void write(CompoundNBT compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
compound.putInt("TransferCooldown", extractionCooldown);
|
||||
if (clientPacket && sendFlap != 0) {
|
||||
compound.putInt("Flap", sendFlap);
|
||||
sendFlap = 0;
|
||||
|
@ -180,6 +242,7 @@ public class FunnelTileEntity extends SmartTileEntity {
|
|||
@Override
|
||||
protected void read(CompoundNBT compound, boolean clientPacket) {
|
||||
super.read(compound, clientPacket);
|
||||
extractionCooldown = compound.getInt("TransferCooldown");
|
||||
if (clientPacket && compound.contains("Flap")) {
|
||||
int direction = compound.getInt("Flap");
|
||||
flap.set(direction);
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.simibubi.create.AllItems;
|
|||
import com.simibubi.create.CreateClient;
|
||||
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPoint.Mode;
|
||||
import com.simibubi.create.foundation.networking.AllPackets;
|
||||
import com.simibubi.create.foundation.utility.Lang;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -21,6 +22,9 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.BlockRayTraceResult;
|
||||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraft.util.text.TextFormatting;
|
||||
import net.minecraft.util.text.TranslationTextComponent;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
|
||||
|
@ -55,6 +59,17 @@ public class ArmInteractionPointHandler {
|
|||
}
|
||||
|
||||
selected.cycleMode();
|
||||
PlayerEntity player = event.getPlayer();
|
||||
if (player != null) {
|
||||
String key = selected.mode == Mode.DEPOSIT ? "mechanical_arm.deposit_to" : "mechanical_arm.extract_from";
|
||||
TextFormatting colour = selected.mode == Mode.DEPOSIT ? TextFormatting.GOLD : TextFormatting.AQUA;
|
||||
String translatedBlock = new TranslationTextComponent(selected.state.getBlock()
|
||||
.getTranslationKey()).getFormattedText();
|
||||
player.sendStatusMessage(
|
||||
new StringTextComponent(colour + Lang.translate(key, TextFormatting.WHITE + translatedBlock + colour)),
|
||||
true);
|
||||
}
|
||||
|
||||
event.setCanceled(true);
|
||||
event.setCancellationResult(ActionResultType.SUCCESS);
|
||||
}
|
||||
|
@ -75,6 +90,20 @@ public class ArmInteractionPointHandler {
|
|||
public static void flushSettings(BlockPos pos) {
|
||||
if (currentItem == null)
|
||||
return;
|
||||
|
||||
int removed = 0;
|
||||
for (Iterator<ArmInteractionPoint> iterator = currentSelection.iterator(); iterator.hasNext();) {
|
||||
ArmInteractionPoint point = iterator.next();
|
||||
if (point.pos.withinDistance(pos, ArmTileEntity.getRange()))
|
||||
continue;
|
||||
iterator.remove();
|
||||
removed++;
|
||||
}
|
||||
|
||||
if (removed > 0)
|
||||
Minecraft.getInstance().player.sendStatusMessage(new StringTextComponent(
|
||||
TextFormatting.RED + Lang.translate("mechanical_arm.points_outside_range", removed)), true);
|
||||
|
||||
AllPackets.channel.sendToServer(new ArmPlacementPacket(currentSelection, pos));
|
||||
currentSelection.clear();
|
||||
currentItem = null;
|
||||
|
|
|
@ -9,6 +9,7 @@ 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;
|
||||
import com.simibubi.create.foundation.advancement.AllTriggers;
|
||||
import com.simibubi.create.foundation.config.AllConfigs;
|
||||
import com.simibubi.create.foundation.gui.AllIcons;
|
||||
import com.simibubi.create.foundation.gui.widgets.InterpolatedAngle;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
@ -328,6 +329,8 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
protected void initInteractionPoints() {
|
||||
if (!updateInteractionPoints || interactionPointTag == null)
|
||||
return;
|
||||
if (!world.isAreaLoaded(pos, getRange() + 1))
|
||||
return;
|
||||
inputs.clear();
|
||||
outputs.clear();
|
||||
for (INBT inbt : interactionPointTag) {
|
||||
|
@ -348,16 +351,21 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
|
||||
ListNBT pointsNBT = new ListNBT();
|
||||
inputs.stream()
|
||||
.map(ArmInteractionPoint::serialize)
|
||||
.forEach(pointsNBT::add);
|
||||
outputs.stream()
|
||||
.map(ArmInteractionPoint::serialize)
|
||||
.forEach(pointsNBT::add);
|
||||
if (updateInteractionPoints) {
|
||||
compound.put("InteractionPoints", interactionPointTag);
|
||||
|
||||
} else {
|
||||
ListNBT pointsNBT = new ListNBT();
|
||||
inputs.stream()
|
||||
.map(ArmInteractionPoint::serialize)
|
||||
.forEach(pointsNBT::add);
|
||||
outputs.stream()
|
||||
.map(ArmInteractionPoint::serialize)
|
||||
.forEach(pointsNBT::add);
|
||||
compound.put("InteractionPoints", pointsNBT);
|
||||
}
|
||||
|
||||
NBTHelper.writeEnum(compound, "Phase", phase);
|
||||
compound.put("InteractionPoints", pointsNBT);
|
||||
compound.put("HeldItem", heldItem.serializeNBT());
|
||||
compound.putInt("TargetPointIndex", chasedPointIndex);
|
||||
compound.putFloat("MovementProgress", chasedPointProgress);
|
||||
|
@ -395,6 +403,10 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
}
|
||||
}
|
||||
|
||||
public static int getRange() {
|
||||
return AllConfigs.SERVER.logistics.mechanicalArmRange.get();
|
||||
}
|
||||
|
||||
private class SelectionModeValueBox extends CenteredSideValueBoxTransform {
|
||||
|
||||
public SelectionModeValueBox() {
|
||||
|
|
|
@ -93,7 +93,7 @@ public class RedstoneLinkTileEntity extends SmartTileEntity {
|
|||
removeBehaviour(LinkBehaviour.TYPE);
|
||||
createLink();
|
||||
link.copyItemsFrom(prevlink);
|
||||
putBehaviour(link);
|
||||
attachBehaviourLate(link);
|
||||
}
|
||||
|
||||
if (transmitter)
|
||||
|
|
|
@ -2,21 +2,23 @@ package com.simibubi.create.foundation.config;
|
|||
|
||||
public class CLogistics extends ConfigBase {
|
||||
|
||||
public ConfigInt extractorDelay = i(20, 10, "extractorDelay", Comments.extractorDelay);
|
||||
public ConfigInt extractorInventoryScanDelay = i(40, 10, "extractorInventoryScanDelay", Comments.extractorInventoryScanDelay);
|
||||
public ConfigInt extractorAmount = i(16, 1, 64, "extractorAmount", Comments.extractorAmount);
|
||||
public ConfigInt defaultExtractionLimit = i(64, 1, 64, "defaultExtractionLimit", Comments.defaultExtractionLimit);
|
||||
public ConfigInt defaultExtractionTimer = i(8, 1, "defaultExtractionTimer", Comments.defaultExtractionTimer);
|
||||
public ConfigInt mechanicalArmRange = i(5, 1, "mechanicalArmRange", Comments.mechanicalArmRange);
|
||||
public ConfigInt linkRange = i(128, 1, "linkRange", Comments.linkRange);
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "logistics";
|
||||
}
|
||||
|
||||
private static class Comments {
|
||||
static String extractorDelay = "The amount of game ticks an Extractor waits after pulling an item successfully.";
|
||||
static String extractorInventoryScanDelay = "The amount of game ticks an Extractor waits before checking again if the attached inventory contains items to extract.";
|
||||
static String extractorAmount = "The amount of items an extractor pulls at a time without an applied filter.";
|
||||
static String defaultExtractionLimit =
|
||||
"The maximum amount of items a funnel pulls at a time without an applied filter.";
|
||||
static String defaultExtractionTimer =
|
||||
"The amount of ticks a funnel waits between item transferrals, when it is not re-activated by redstone.";
|
||||
static String linkRange = "Maximum possible range in blocks of redstone link connections.";
|
||||
static String mechanicalArmRange = "Maximum distance in blocks a Mechanical Arm can reach across.";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -83,6 +83,7 @@ public class AllIcons {
|
|||
I_TUNNEL_FORCED_ROUND_ROBIN = next(),
|
||||
I_TUNNEL_PREFER_NEAREST = next(),
|
||||
I_TUNNEL_RANDOMIZE = next(),
|
||||
I_TUNNEL_SYNCHRONIZE = next(),
|
||||
|
||||
I_TOOL_MOVE_XZ = newRow(),
|
||||
I_TOOL_MOVE_Y = next(),
|
||||
|
|
|
@ -134,7 +134,7 @@ public class ItemHelper {
|
|||
}
|
||||
|
||||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test, boolean simulate) {
|
||||
return extract(inv, test, ExtractionCountMode.UPTO, AllConfigs.SERVER.logistics.extractorAmount.get(),
|
||||
return extract(inv, test, ExtractionCountMode.UPTO, AllConfigs.SERVER.logistics.defaultExtractionLimit.get(),
|
||||
simulate);
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,7 @@ public class ItemHelper {
|
|||
public static ItemStack extract(IItemHandler inv, Predicate<ItemStack> test,
|
||||
Function<ItemStack, Integer> amountFunction, boolean simulate) {
|
||||
ItemStack extracting = ItemStack.EMPTY;
|
||||
int maxExtractionCount = AllConfigs.SERVER.logistics.extractorAmount.get();
|
||||
int maxExtractionCount = AllConfigs.SERVER.logistics.defaultExtractionLimit.get();
|
||||
|
||||
for (int slot = 0; slot < inv.getSlots(); slot++) {
|
||||
if (extracting.isEmpty()) {
|
||||
|
|
|
@ -78,7 +78,7 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
|||
public final void readClientUpdate(CompoundNBT tag) {
|
||||
read(tag, true);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void read(CompoundNBT tag) {
|
||||
read(tag, false);
|
||||
|
@ -99,7 +99,6 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
|||
.forEach(tb -> tb.read(compound, clientPacket));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Hook only these in future subclasses of STE
|
||||
*/
|
||||
|
@ -126,13 +125,10 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
|||
|
||||
protected void forEachBehaviour(Consumer<TileEntityBehaviour> action) {
|
||||
behaviours.values()
|
||||
.forEach(tb -> {
|
||||
if (!tb.isPaused())
|
||||
action.accept(tb);
|
||||
});
|
||||
.forEach(action);
|
||||
}
|
||||
|
||||
protected void putBehaviour(TileEntityBehaviour behaviour) {
|
||||
protected void attachBehaviourLate(TileEntityBehaviour behaviour) {
|
||||
behaviours.put(behaviour.getType(), behaviour);
|
||||
behaviour.initialize();
|
||||
}
|
||||
|
@ -144,7 +140,7 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
protected <T extends TileEntityBehaviour> T getBehaviour(BehaviourType<T> type) {
|
||||
public <T extends TileEntityBehaviour> T getBehaviour(BehaviourType<T> type) {
|
||||
if (behaviours.containsKey(type))
|
||||
return (T) behaviours.get(type);
|
||||
return null;
|
||||
|
|
|
@ -13,13 +13,11 @@ import net.minecraft.world.World;
|
|||
public abstract class TileEntityBehaviour {
|
||||
|
||||
public SmartTileEntity tileEntity;
|
||||
private boolean paused;
|
||||
private int lazyTickRate;
|
||||
private int lazyTickCounter;
|
||||
|
||||
public TileEntityBehaviour(SmartTileEntity te) {
|
||||
tileEntity = te;
|
||||
paused = false;
|
||||
setLazyTickRate(10);
|
||||
}
|
||||
|
||||
|
@ -34,13 +32,13 @@ public abstract class TileEntityBehaviour {
|
|||
lazyTickCounter = lazyTickRate;
|
||||
lazyTick();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void read(CompoundNBT nbt, boolean clientPacket) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
|
||||
}
|
||||
|
@ -55,14 +53,10 @@ public abstract class TileEntityBehaviour {
|
|||
|
||||
public void remove() {
|
||||
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
public boolean isPaused() {
|
||||
return paused;
|
||||
public void destroy() {
|
||||
|
||||
}
|
||||
|
||||
public void setLazyTickRate(int slowTickRate) {
|
||||
|
@ -74,10 +68,6 @@ public abstract class TileEntityBehaviour {
|
|||
|
||||
}
|
||||
|
||||
public void setPaused(boolean paused) {
|
||||
this.paused = paused;
|
||||
}
|
||||
|
||||
public BlockPos getPos() {
|
||||
return tileEntity.getPos();
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.tileEntity.behaviour.filtering;
|
|||
|
||||
import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -32,7 +31,7 @@ public class FilteringCountUpdatePacket extends TileEntityConfigurationPacket<Sm
|
|||
|
||||
@Override
|
||||
protected void applySettings(SmartTileEntity te) {
|
||||
FilteringBehaviour behaviour = TileEntityBehaviour.get(te, FilteringBehaviour.TYPE);
|
||||
FilteringBehaviour behaviour = te.getBehaviour(FilteringBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
behaviour.forceClientState = true;
|
||||
|
|
|
@ -87,7 +87,7 @@ public class FilteringRenderer {
|
|||
|
||||
if (tileEntityIn == null || tileEntityIn.isRemoved())
|
||||
return;
|
||||
FilteringBehaviour behaviour = TileEntityBehaviour.get(tileEntityIn, FilteringBehaviour.TYPE);
|
||||
FilteringBehaviour behaviour = tileEntityIn.getBehaviour(FilteringBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (!behaviour.isActive())
|
||||
|
|
|
@ -25,13 +25,33 @@ import net.minecraftforge.items.ItemHandlerHelper;
|
|||
|
||||
public class InvManipulationBehaviour extends TileEntityBehaviour {
|
||||
|
||||
public static BehaviourType<InvManipulationBehaviour> TYPE = new BehaviourType<>();
|
||||
private InterfaceProvider target;
|
||||
private LazyOptional<IItemHandler> targetCapability;
|
||||
private boolean simulateNext;
|
||||
// Extra types available for multibehaviour
|
||||
public static BehaviourType<InvManipulationBehaviour>
|
||||
|
||||
TYPE = new BehaviourType<>(), EXTRACT = new BehaviourType<>(), INSERT = new BehaviourType<>();
|
||||
|
||||
protected InterfaceProvider target;
|
||||
protected LazyOptional<IItemHandler> targetCapability;
|
||||
protected boolean simulateNext;
|
||||
|
||||
private BehaviourType<InvManipulationBehaviour> behaviourType;
|
||||
|
||||
public static InvManipulationBehaviour forExtraction(SmartTileEntity te, InterfaceProvider target) {
|
||||
return new InvManipulationBehaviour(EXTRACT, te, target);
|
||||
}
|
||||
|
||||
public static InvManipulationBehaviour forInsertion(SmartTileEntity te, InterfaceProvider target) {
|
||||
return new InvManipulationBehaviour(INSERT, te, target);
|
||||
}
|
||||
|
||||
public InvManipulationBehaviour(SmartTileEntity te, InterfaceProvider target) {
|
||||
this(TYPE, te, target);
|
||||
}
|
||||
|
||||
private InvManipulationBehaviour(BehaviourType<InvManipulationBehaviour> type, SmartTileEntity te,
|
||||
InterfaceProvider target) {
|
||||
super(te);
|
||||
behaviourType = type;
|
||||
setLazyTickRate(40);
|
||||
this.target = target;
|
||||
this.targetCapability = LazyOptional.empty();
|
||||
|
@ -94,7 +114,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
|
|||
|
||||
protected Predicate<ItemStack> getFilterTest(Predicate<ItemStack> customFilter) {
|
||||
Predicate<ItemStack> test = customFilter;
|
||||
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
|
||||
FilteringBehaviour filter = tileEntity.getBehaviour(FilteringBehaviour.TYPE);
|
||||
if (filter != null)
|
||||
test = customFilter.and(filter::test);
|
||||
return test;
|
||||
|
@ -119,7 +139,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
|
|||
|
||||
public int getAmountFromFilter() {
|
||||
int amount = -1;
|
||||
FilteringBehaviour filter = get(tileEntity, FilteringBehaviour.TYPE);
|
||||
FilteringBehaviour filter = tileEntity.getBehaviour(FilteringBehaviour.TYPE);
|
||||
if (filter != null && !filter.anyAmount())
|
||||
amount = filter.getAmount();
|
||||
return amount;
|
||||
|
@ -146,7 +166,7 @@ public class InvManipulationBehaviour extends TileEntityBehaviour {
|
|||
|
||||
@Override
|
||||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
return behaviourType;
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
|
|
|
@ -57,12 +57,12 @@ public class LinkRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
public static void renderOnTileEntity(SmartTileEntity tileEntityIn, float partialTicks, MatrixStack ms,
|
||||
public static void renderOnTileEntity(SmartTileEntity te, float partialTicks, MatrixStack ms,
|
||||
IRenderTypeBuffer buffer, int light, int overlay) {
|
||||
|
||||
if (tileEntityIn == null || tileEntityIn.isRemoved())
|
||||
if (te == null || te.isRemoved())
|
||||
return;
|
||||
LinkBehaviour behaviour = TileEntityBehaviour.get(tileEntityIn, LinkBehaviour.TYPE);
|
||||
LinkBehaviour behaviour = te.getBehaviour(LinkBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
|
||||
|
@ -71,7 +71,7 @@ public class LinkRenderer {
|
|||
ItemStack stack = first ? behaviour.frequencyFirst.getStack() : behaviour.frequencyLast.getStack();
|
||||
|
||||
ms.push();
|
||||
transform.transform(tileEntityIn.getBlockState(), ms);
|
||||
transform.transform(te.getBlockState(), ms);
|
||||
ValueBoxRenderer.renderItemIntoValueBox(stack, ms, buffer, light, overlay);
|
||||
ms.pop();
|
||||
}
|
||||
|
|
|
@ -45,8 +45,8 @@ public class ScrollValueHandler {
|
|||
|
||||
if (scrolling instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) {
|
||||
BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) scrolling;
|
||||
for (SmartTileEntity smartTileEntity : bulkScrolling.getBulk()) {
|
||||
ScrollValueBehaviour other = TileEntityBehaviour.get(smartTileEntity, ScrollValueBehaviour.TYPE);
|
||||
for (SmartTileEntity te : bulkScrolling.getBulk()) {
|
||||
ScrollValueBehaviour other = te.getBehaviour(ScrollValueBehaviour.TYPE);
|
||||
if (other != null)
|
||||
applyTo(delta, other);
|
||||
}
|
||||
|
|
|
@ -35,15 +35,14 @@ public class ScrollValueRenderer {
|
|||
ScrollValueBehaviour behaviour = TileEntityBehaviour.get(world, pos, ScrollValueBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
if (behaviour.needsWrench
|
||||
&& !AllItems.WRENCH.isIn(Minecraft.getInstance().player.getHeldItemMainhand()))
|
||||
if (behaviour.needsWrench && !AllItems.WRENCH.isIn(Minecraft.getInstance().player.getHeldItemMainhand()))
|
||||
return;
|
||||
boolean highlight = behaviour.testHit(target.getHitVec());
|
||||
|
||||
if (behaviour instanceof BulkScrollValueBehaviour && AllKeys.ctrlDown()) {
|
||||
BulkScrollValueBehaviour bulkScrolling = (BulkScrollValueBehaviour) behaviour;
|
||||
for (SmartTileEntity smartTileEntity : bulkScrolling.getBulk()) {
|
||||
ScrollValueBehaviour other = TileEntityBehaviour.get(smartTileEntity, ScrollValueBehaviour.TYPE);
|
||||
ScrollValueBehaviour other = smartTileEntity.getBehaviour(ScrollValueBehaviour.TYPE);
|
||||
if (other != null)
|
||||
addBox(world, smartTileEntity.getPos(), face, other, highlight);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue;
|
|||
|
||||
import com.simibubi.create.foundation.networking.TileEntityConfigurationPacket;
|
||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
|
@ -32,7 +31,7 @@ public class ScrollValueUpdatePacket extends TileEntityConfigurationPacket<Smart
|
|||
|
||||
@Override
|
||||
protected void applySettings(SmartTileEntity te) {
|
||||
ScrollValueBehaviour behaviour = TileEntityBehaviour.get(te, ScrollValueBehaviour.TYPE);
|
||||
ScrollValueBehaviour behaviour = te.getBehaviour(ScrollValueBehaviour.TYPE);
|
||||
if (behaviour == null)
|
||||
return;
|
||||
behaviour.setValue(value);
|
||||
|
|
|
@ -16,10 +16,12 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.state.properties.BlockStateProperties;
|
||||
import net.minecraft.state.properties.SlabType;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.shapes.VoxelShape;
|
||||
import net.minecraft.world.GameRules;
|
||||
import net.minecraft.world.IBlockReader;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
|
@ -65,25 +67,25 @@ public class BlockHelper {
|
|||
}
|
||||
|
||||
public static BlockState setZeroAge(BlockState blockState) {
|
||||
if(blockState.has(BlockStateProperties.AGE_0_1))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_1))
|
||||
return blockState.with(BlockStateProperties.AGE_0_1, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_2))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_2))
|
||||
return blockState.with(BlockStateProperties.AGE_0_2, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_3))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_3))
|
||||
return blockState.with(BlockStateProperties.AGE_0_3, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_5))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_5))
|
||||
return blockState.with(BlockStateProperties.AGE_0_5, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_7))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_7))
|
||||
return blockState.with(BlockStateProperties.AGE_0_7, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_15))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_15))
|
||||
return blockState.with(BlockStateProperties.AGE_0_15, 0);
|
||||
if(blockState.has(BlockStateProperties.AGE_0_25))
|
||||
if (blockState.has(BlockStateProperties.AGE_0_25))
|
||||
return blockState.with(BlockStateProperties.AGE_0_25, 0);
|
||||
if(blockState.has(BlockStateProperties.HONEY_LEVEL))
|
||||
if (blockState.has(BlockStateProperties.HONEY_LEVEL))
|
||||
return blockState.with(BlockStateProperties.HONEY_LEVEL, 0);
|
||||
if(blockState.has(BlockStateProperties.HATCH_0_2))
|
||||
if (blockState.has(BlockStateProperties.HATCH_0_2))
|
||||
return blockState.with(BlockStateProperties.HATCH_0_2, 0);
|
||||
if(blockState.has(BlockStateProperties.STAGE_0_1))
|
||||
if (blockState.has(BlockStateProperties.STAGE_0_1))
|
||||
return blockState.with(BlockStateProperties.STAGE_0_1, 0);
|
||||
return blockState;
|
||||
}
|
||||
|
@ -98,10 +100,10 @@ public class BlockHelper {
|
|||
if (needsTwo)
|
||||
amount *= 2;
|
||||
|
||||
if(block.has(BlockStateProperties.EGGS_1_4))
|
||||
if (block.has(BlockStateProperties.EGGS_1_4))
|
||||
amount *= block.get(BlockStateProperties.EGGS_1_4);
|
||||
|
||||
if(block.has(BlockStateProperties.PICKLES_1_4))
|
||||
if (block.has(BlockStateProperties.PICKLES_1_4))
|
||||
amount *= block.get(BlockStateProperties.PICKLES_1_4);
|
||||
|
||||
{
|
||||
|
@ -172,4 +174,13 @@ public class BlockHelper {
|
|||
world.setBlockState(pos, ifluidstate.getBlockState());
|
||||
}
|
||||
|
||||
public static boolean isSolidWall(IBlockReader reader, BlockPos fromPos, Direction toDirection) {
|
||||
return Block.hasSolidSide(reader.getBlockState(fromPos.offset(toDirection)), reader,
|
||||
fromPos.offset(toDirection), toDirection.getOpposite());
|
||||
}
|
||||
|
||||
public static boolean noCollisionInSpace(IBlockReader reader, BlockPos pos) {
|
||||
return reader.getBlockState(pos).getCollisionShape(reader, pos).isEmpty();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -342,9 +342,13 @@
|
|||
"create.tooltip.generationSpeed" : "Generates at %1$s %2$s",
|
||||
|
||||
"create.tooltip.analogStrength": "Analog Strength: %1$s/15",
|
||||
|
||||
"create.mechanical_arm.extract_from": "Take items from %1$s",
|
||||
"create.mechanical_arm.deposit_to": "Deposit items to %1$s",
|
||||
"create.mechanical_arm.points_outside_range": "%1$s selected interaction point(s) removed due to range limitations.",
|
||||
|
||||
"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",
|
||||
|
@ -355,6 +359,7 @@
|
|||
"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.tunnel.selection_mode.synchronize": "Synchronize Inputs",
|
||||
|
||||
"create.gui.config.overlay1": "Hi :)",
|
||||
"create.gui.config.overlay2": "This is a sample overlay",
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
"north": {"uv": [0, 8, 1, 9.5], "texture": "#7"},
|
||||
"east": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
|
||||
"south": {"uv": [15, 8, 16, 9.5], "texture": "#7"},
|
||||
"west": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"}
|
||||
"west": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [14, 10, 16, 16], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -31,7 +32,8 @@
|
|||
"north": {"uv": [7, 8, 8, 9.5], "texture": "#7"},
|
||||
"east": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
|
||||
"south": {"uv": [8, 7.5, 9, 9], "texture": "#7"},
|
||||
"west": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"}
|
||||
"west": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 10, 2, 16], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -80,7 +82,8 @@
|
|||
"faces": {
|
||||
"north": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#7"},
|
||||
"east": {"uv": [5, 15, 8, 16], "texture": "#7"},
|
||||
"west": {"uv": [5, 15, 8, 16], "texture": "#7"}
|
||||
"west": {"uv": [5, 15, 8, 16], "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -91,7 +94,8 @@
|
|||
"faces": {
|
||||
"north": {"uv": [7.5, 9.5, 8, 10.5], "texture": "#7"},
|
||||
"east": {"uv": [8, 15, 5, 16], "texture": "#7"},
|
||||
"west": {"uv": [8, 15, 5, 16], "texture": "#7"}
|
||||
"west": {"uv": [8, 15, 5, 16], "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -165,7 +169,8 @@
|
|||
"faces": {
|
||||
"east": {"uv": [0, 14.5, 5, 16], "texture": "#7"},
|
||||
"south": {"uv": [7.5, 14.5, 8, 16], "texture": "#7"},
|
||||
"up": {"uv": [0, 14.5, 5.5, 15], "rotation": 270, "texture": "#7"}
|
||||
"up": {"uv": [0, 14.5, 5.5, 15], "rotation": 270, "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 10], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -176,7 +181,8 @@
|
|||
"faces": {
|
||||
"south": {"uv": [0, 14.5, 0.5, 16], "texture": "#7"},
|
||||
"west": {"uv": [5, 14.5, 0, 16], "texture": "#7"},
|
||||
"up": {"uv": [0, 15, 5.5, 14.5], "rotation": 270, "texture": "#7"}
|
||||
"up": {"uv": [0, 15, 5.5, 14.5], "rotation": 270, "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 10], "texture": "#particle"}
|
||||
}
|
||||
}
|
||||
],
|
||||
|
|
|
@ -19,7 +19,8 @@
|
|||
"north": {"uv": [0, 8, 1, 9.5], "texture": "#7"},
|
||||
"east": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
|
||||
"south": {"uv": [15, 8, 16, 9.5], "texture": "#7"},
|
||||
"west": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"}
|
||||
"west": {"uv": [13, 0, 16, 6], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [14, 10, 16, 16], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -31,7 +32,8 @@
|
|||
"north": {"uv": [7, 8, 8, 9.5], "texture": "#7"},
|
||||
"east": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
|
||||
"south": {"uv": [8, 7.5, 9, 9], "texture": "#7"},
|
||||
"west": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"}
|
||||
"west": {"uv": [13, 6, 16, 0], "rotation": 90, "texture": "#2"},
|
||||
"down": {"uv": [0, 10, 2, 16], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -90,7 +92,8 @@
|
|||
"faces": {
|
||||
"north": {"uv": [0, 9.5, 0.5, 10.5], "texture": "#7"},
|
||||
"east": {"uv": [5, 15, 8, 16], "texture": "#7"},
|
||||
"west": {"uv": [5, 15, 8, 16], "texture": "#7"}
|
||||
"west": {"uv": [5, 15, 8, 16], "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -101,7 +104,8 @@
|
|||
"faces": {
|
||||
"north": {"uv": [7.5, 9.5, 8, 10.5], "texture": "#7"},
|
||||
"east": {"uv": [8, 15, 5, 16], "texture": "#7"},
|
||||
"west": {"uv": [8, 15, 5, 16], "texture": "#7"}
|
||||
"west": {"uv": [8, 15, 5, 16], "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 6], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -149,7 +153,9 @@
|
|||
"faces": {
|
||||
"east": {"uv": [0, 14.5, 1, 16], "texture": "#7"},
|
||||
"south": {"uv": [7.5, 14.5, 8, 16], "texture": "#7"},
|
||||
"up": {"uv": [0, 14.5, 5.5, 15], "rotation": 270, "texture": "#7"}
|
||||
"west": {"uv": [7, 14.5, 8, 16], "texture": "#7"},
|
||||
"up": {"uv": [0, 14.5, 5.5, 15], "rotation": 270, "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 2], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -158,9 +164,11 @@
|
|||
"to": [1, -2, 16],
|
||||
"rotation": {"angle": 0, "axis": "y", "origin": [8, -8, 6]},
|
||||
"faces": {
|
||||
"east": {"uv": [8, 14.5, 7, 16], "texture": "#7"},
|
||||
"south": {"uv": [0, 14.5, 0.5, 16], "texture": "#7"},
|
||||
"west": {"uv": [1, 14.5, 0, 16], "texture": "#7"},
|
||||
"up": {"uv": [0, 15, 5.5, 14.5], "rotation": 270, "texture": "#7"}
|
||||
"up": {"uv": [0, 15, 5.5, 14.5], "rotation": 270, "texture": "#7"},
|
||||
"down": {"uv": [0, 0, 1, 2], "texture": "#particle"}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
12
src/main/resources/assets/create/particles/air.json
Normal file
12
src/main/resources/assets/create/particles/air.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"textures": [
|
||||
"minecraft:generic_7",
|
||||
"minecraft:generic_6",
|
||||
"minecraft:generic_5",
|
||||
"minecraft:generic_4",
|
||||
"minecraft:generic_3",
|
||||
"minecraft:generic_2",
|
||||
"minecraft:generic_1",
|
||||
"minecraft:generic_0"
|
||||
]
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 405 B |
Binary file not shown.
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Loading…
Reference in a new issue