mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-18 16:02:19 +01:00
Superglue
- Added superglue, an alternative to chassis blocks - Added some random safety checks - Fixed some more bad gl states left by event handlers
This commit is contained in:
parent
db8e52be2e
commit
c62d356f9b
30 changed files with 946 additions and 40 deletions
|
@ -5,6 +5,8 @@ import java.util.function.Function;
|
||||||
import com.simibubi.create.foundation.utility.Lang;
|
import com.simibubi.create.foundation.utility.Lang;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionEntityRenderer;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueRenderer;
|
||||||
|
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.entity.EntityClassification;
|
import net.minecraft.entity.EntityClassification;
|
||||||
|
@ -23,6 +25,8 @@ public enum AllEntities {
|
||||||
ContraptionEntity::build),
|
ContraptionEntity::build),
|
||||||
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
||||||
false, ContraptionEntity::build),
|
false, ContraptionEntity::build),
|
||||||
|
SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 30, Integer.MAX_VALUE, false, SuperGlueEntity::build),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
private IFactory<?> factory;
|
private IFactory<?> factory;
|
||||||
|
@ -62,8 +66,8 @@ public enum AllEntities {
|
||||||
|
|
||||||
@OnlyIn(value = Dist.CLIENT)
|
@OnlyIn(value = Dist.CLIENT)
|
||||||
public static void registerRenderers() {
|
public static void registerRenderers() {
|
||||||
// RenderingRegistry.registerEntityRenderingHandler(CardboardBoxEntity.class, CardboardBoxEntityRenderer::new);
|
|
||||||
RenderingRegistry.registerEntityRenderingHandler(ContraptionEntity.class, ContraptionEntityRenderer::new);
|
RenderingRegistry.registerEntityRenderingHandler(ContraptionEntity.class, ContraptionEntityRenderer::new);
|
||||||
|
RenderingRegistry.registerEntityRenderingHandler(SuperGlueEntity.class, SuperGlueRenderer::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import com.simibubi.create.foundation.utility.data.ITaggable;
|
||||||
import com.simibubi.create.modules.IModule;
|
import com.simibubi.create.modules.IModule;
|
||||||
import com.simibubi.create.modules.contraptions.GogglesItem;
|
import com.simibubi.create.modules.contraptions.GogglesItem;
|
||||||
import com.simibubi.create.modules.contraptions.WrenchItem;
|
import com.simibubi.create.modules.contraptions.WrenchItem;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueItem;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
|
import com.simibubi.create.modules.contraptions.relays.belt.item.BeltConnectorItem;
|
||||||
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
|
import com.simibubi.create.modules.contraptions.relays.gearbox.VerticalGearboxItem;
|
||||||
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
||||||
|
@ -76,7 +77,7 @@ public enum AllItems {
|
||||||
BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")),
|
BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")),
|
||||||
|
|
||||||
FLOUR,
|
FLOUR,
|
||||||
DOUGH,
|
DOUGH,
|
||||||
OBSIDIAN_DUST,
|
OBSIDIAN_DUST,
|
||||||
ROSE_QUARTZ,
|
ROSE_QUARTZ,
|
||||||
POLISHED_ROSE_QUARTZ,
|
POLISHED_ROSE_QUARTZ,
|
||||||
|
@ -93,8 +94,7 @@ public enum AllItems {
|
||||||
WHISK,
|
WHISK,
|
||||||
BRASS_HAND,
|
BRASS_HAND,
|
||||||
SLOT_COVER,
|
SLOT_COVER,
|
||||||
SUPER_GLUE,
|
SUPER_GLUE(SuperGlueItem::new),
|
||||||
ANTIOXIDANT,
|
|
||||||
SAND_PAPER(SandPaperItem::new),
|
SAND_PAPER(SandPaperItem::new),
|
||||||
RED_SAND_PAPER(SandPaperItem::new),
|
RED_SAND_PAPER(SandPaperItem::new),
|
||||||
WRENCH(WrenchItem::new),
|
WRENCH(WrenchItem::new),
|
||||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.CancelPlayerFallPacket;
|
import com.simibubi.create.modules.contraptions.components.contraptions.CancelPlayerFallPacket;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket;
|
import com.simibubi.create.modules.contraptions.components.contraptions.ContraptionStallPacket;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.GlueEffectPacket;
|
||||||
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
import com.simibubi.create.modules.contraptions.relays.advanced.sequencer.ConfigureSequencedGearshiftPacket;
|
||||||
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
import com.simibubi.create.modules.curiosities.symmetry.SymmetryEffectPacket;
|
||||||
import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket;
|
import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket;
|
||||||
|
@ -51,6 +52,7 @@ public enum AllPackets {
|
||||||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
||||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::new),
|
||||||
TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new),
|
TOOL_HARVEST(AbstractToolItem.HarvestPacket.class, AbstractToolItem.HarvestPacket::new),
|
||||||
|
GLUE_EFFECT(GlueEffectPacket.class, GlueEffectPacket::new),
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ public class CClient extends ConfigBase {
|
||||||
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");
|
public ConfigFloat fanParticleDensity = f(.5f, 0, 1, "fanParticleDensity");
|
||||||
public ConfigBool rainbowDebug =
|
public ConfigBool rainbowDebug =
|
||||||
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");
|
b(true, "enableRainbowDebug", "Show colourful debug information while the F3-Menu is open.");
|
||||||
|
public ConfigBool showHiddenSuperGlue =
|
||||||
|
b(false, "showHiddenSuperGlue", "Show indications for hidden glue between blocks while holding the item.");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
|
|
@ -5,9 +5,9 @@ public class CDamageControl extends ConfigBase {
|
||||||
public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing);
|
public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing);
|
||||||
public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors);
|
public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors);
|
||||||
public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing);
|
public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing);
|
||||||
public ConfigBool freezeRotationPropagator = b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
public ConfigBool freezeRotationPropagator =
|
||||||
public ConfigBool freezeBearingConstructs = b(false, "freezeBearingConstructs", Comments.freezeBearingConstructs);
|
b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
||||||
public ConfigBool freezePistonConstructs = b(false, "freezePistonConstructs", Comments.freezePistonConstructs);
|
public ConfigBool freezeContraptions = b(false, "freezeContraptions", Comments.freezeContraptions);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getName() {
|
public String getName() {
|
||||||
|
@ -20,8 +20,7 @@ public class CDamageControl extends ConfigBase {
|
||||||
static String freezeInWorldProcessing = "In case Encased Fans tried smelting your hardware.";
|
static String freezeInWorldProcessing = "In case Encased Fans tried smelting your hardware.";
|
||||||
static String freezeRotationPropagator =
|
static String freezeRotationPropagator =
|
||||||
"Pauses rotation logic altogether - Use if crash mentions RotationPropagators.";
|
"Pauses rotation logic altogether - Use if crash mentions RotationPropagators.";
|
||||||
static String freezeBearingConstructs = "In case Mechanical Bearings turned against you.";
|
static String freezeContraptions = "In case Moving contraptions pushed it too far.";
|
||||||
static String freezePistonConstructs = "In case Mechanical Pistons pushed it too far.";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ public class ValueBoxRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
box.render(highlighted);
|
box.render(highlighted);
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
GlStateManager.disableAlphaTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void renderText(ValueBox box, FontRenderer font, String text) {
|
public static void renderText(ValueBox box, FontRenderer font, String text) {
|
||||||
|
|
|
@ -60,6 +60,7 @@ public class ScrollValueRenderer {
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
render(world, pos, face, behaviour, highlight);
|
render(world, pos, face, behaviour, highlight);
|
||||||
|
|
||||||
TessellatorHelper.cleanUpAfterDrawing();
|
TessellatorHelper.cleanUpAfterDrawing();
|
||||||
GlStateManager.enableAlphaTest();
|
GlStateManager.enableAlphaTest();
|
||||||
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||||
|
|
|
@ -67,10 +67,9 @@ public class ScreenElementRenderer {
|
||||||
BlockRendererDispatcher blockRenderer = mc.getBlockRendererDispatcher();
|
BlockRendererDispatcher blockRenderer = mc.getBlockRendererDispatcher();
|
||||||
IBakedModel modelToRender = null;
|
IBakedModel modelToRender = null;
|
||||||
BlockState blockToRender = null;
|
BlockState blockToRender = null;
|
||||||
boolean stateMode = transformsAndModel == null;
|
|
||||||
boolean fire = false;
|
boolean fire = false;
|
||||||
|
|
||||||
if (stateMode) {
|
if (transformsAndModel == null) {
|
||||||
blockToRender = transformsAndState.get();
|
blockToRender = transformsAndState.get();
|
||||||
fire = (blockToRender.getBlock() instanceof FireBlock);
|
fire = (blockToRender.getBlock() instanceof FireBlock);
|
||||||
modelToRender = blockRenderer.getModelForState(blockToRender);
|
modelToRender = blockRenderer.getModelForState(blockToRender);
|
||||||
|
@ -81,7 +80,6 @@ public class ScreenElementRenderer {
|
||||||
GlStateManager.scaled(50, -50, 50);
|
GlStateManager.scaled(50, -50, 50);
|
||||||
mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||||
|
|
||||||
|
|
||||||
GlStateManager.pushMatrix();
|
GlStateManager.pushMatrix();
|
||||||
if (fire) {
|
if (fire) {
|
||||||
blockRenderer.renderBlockBrightness(blockToRender, 1);
|
blockRenderer.renderBlockBrightness(blockToRender, 1);
|
||||||
|
@ -97,7 +95,7 @@ public class ScreenElementRenderer {
|
||||||
}
|
}
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
|
|
||||||
if (stateMode && !blockToRender.getFluidState().isEmpty()) {
|
if (blockToRender != null && !blockToRender.getFluidState().isEmpty()) {
|
||||||
RenderHelper.disableStandardItemLighting();
|
RenderHelper.disableStandardItemLighting();
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.util.math.BlockPos;
|
||||||
public class Iterate {
|
public class Iterate {
|
||||||
|
|
||||||
public static final boolean[] trueAndFalse = { true, false };
|
public static final boolean[] trueAndFalse = { true, false };
|
||||||
|
public static final int[] zeroAndOne = { 1, -1 };
|
||||||
public static final int[] positiveAndNegative = { 1, -1 };
|
public static final int[] positiveAndNegative = { 1, -1 };
|
||||||
public static final Direction[] directions = Direction.values();
|
public static final Direction[] directions = Direction.values();
|
||||||
public static final Direction[] horizontalDirections = getHorizontals();
|
public static final Direction[] horizontalDirections = getHorizontals();
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.fluid.IFluidState;
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockReader;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
|
||||||
|
public class RayTraceWorld implements IBlockReader {
|
||||||
|
|
||||||
|
private IWorld template;
|
||||||
|
private BiFunction<BlockPos, BlockState, BlockState> stateGetter;
|
||||||
|
|
||||||
|
public RayTraceWorld(IWorld template, BiFunction<BlockPos, BlockState, BlockState> stateGetter) {
|
||||||
|
this.template = template;
|
||||||
|
this.stateGetter = stateGetter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TileEntity getTileEntity(BlockPos pos) {
|
||||||
|
return template.getTileEntity(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState(BlockPos pos) {
|
||||||
|
return stateGetter.apply(pos, template.getBlockState(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IFluidState getFluidState(BlockPos pos) {
|
||||||
|
return template.getFluidState(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -69,7 +69,6 @@ public class TessellatorHelper {
|
||||||
public static void cleanUpAfterDrawing() {
|
public static void cleanUpAfterDrawing() {
|
||||||
GlStateManager.popAttributes();
|
GlStateManager.popAttributes();
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
GlStateManager.disableAlphaTest();
|
|
||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,16 @@ import com.simibubi.create.foundation.utility.WrappedWorld;
|
||||||
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
import com.simibubi.create.modules.contraptions.base.KineticTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.AbstractChassisBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
import com.simibubi.create.modules.contraptions.components.contraptions.chassis.ChassisTileEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueEntity;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.glue.SuperGlueHandler;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonBlock.PistonState;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.MechanicalPistonHeadBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.piston.PistonPoleBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.MagnetBlock;
|
||||||
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock;
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyBlock.RopeBlock;
|
||||||
|
import com.simibubi.create.modules.contraptions.components.contraptions.pulley.PulleyTileEntity;
|
||||||
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
import com.simibubi.create.modules.contraptions.components.saw.SawBlock;
|
||||||
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
import com.simibubi.create.modules.contraptions.redstone.ContactBlock;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||||
|
@ -74,6 +76,7 @@ public abstract class Contraption {
|
||||||
public List<MutablePair<BlockInfo, MovementContext>> actors;
|
public List<MutablePair<BlockInfo, MovementContext>> actors;
|
||||||
public CombinedInvWrapper inventory;
|
public CombinedInvWrapper inventory;
|
||||||
public List<TileEntity> customRenderTEs;
|
public List<TileEntity> customRenderTEs;
|
||||||
|
public Set<Pair<BlockPos, Direction>> superglue;
|
||||||
|
|
||||||
public AxisAlignedBB bounds;
|
public AxisAlignedBB bounds;
|
||||||
public boolean stalled;
|
public boolean stalled;
|
||||||
|
@ -83,13 +86,16 @@ public abstract class Contraption {
|
||||||
protected BlockPos anchor;
|
protected BlockPos anchor;
|
||||||
|
|
||||||
List<BlockPos> renderOrder;
|
List<BlockPos> renderOrder;
|
||||||
|
List<SuperGlueEntity> glueToRemove;
|
||||||
|
|
||||||
public Contraption() {
|
public Contraption() {
|
||||||
blocks = new HashMap<>();
|
blocks = new HashMap<>();
|
||||||
storage = new HashMap<>();
|
storage = new HashMap<>();
|
||||||
actors = new ArrayList<>();
|
actors = new ArrayList<>();
|
||||||
|
superglue = new HashSet<>();
|
||||||
renderOrder = new ArrayList<>();
|
renderOrder = new ArrayList<>();
|
||||||
customRenderTEs = new ArrayList<>();
|
customRenderTEs = new ArrayList<>();
|
||||||
|
glueToRemove = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
|
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
|
||||||
|
@ -242,6 +248,8 @@ public abstract class Contraption {
|
||||||
frontier.add(otherPartPos);
|
frontier.add(otherPartPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
|
||||||
|
|
||||||
// Slime blocks drag adjacent blocks if possible
|
// Slime blocks drag adjacent blocks if possible
|
||||||
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
|
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
|
||||||
for (Direction offset : Direction.values()) {
|
for (Direction offset : Direction.values()) {
|
||||||
|
@ -254,9 +262,18 @@ public abstract class Contraption {
|
||||||
return false;
|
return false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!visited.contains(offsetPos) && ((isSlimeBlock && !BlockMovementTraits.isBrittle(blockState))
|
|
||||||
|| BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite())))
|
boolean wasVisited = visited.contains(offsetPos);
|
||||||
|
boolean faceHasGlue = superglue.containsKey(offset);
|
||||||
|
boolean blockAttachedTowardsFace =
|
||||||
|
BlockMovementTraits.isBlockAttachedTowards(blockState, offset.getOpposite());
|
||||||
|
boolean brittle = BlockMovementTraits.isBrittle(blockState);
|
||||||
|
|
||||||
|
if (!wasVisited && ((isSlimeBlock && !brittle) || blockAttachedTowardsFace || faceHasGlue))
|
||||||
frontier.add(offsetPos);
|
frontier.add(offsetPos);
|
||||||
|
|
||||||
|
if (faceHasGlue)
|
||||||
|
addGlue(superglue.get(offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
add(pos, capture(world, pos));
|
add(pos, capture(world, pos));
|
||||||
|
@ -325,6 +342,14 @@ public abstract class Contraption {
|
||||||
return compoundnbt;
|
return compoundnbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addGlue(SuperGlueEntity entity) {
|
||||||
|
BlockPos pos = entity.getHangingPosition();
|
||||||
|
Direction direction = entity.getFacingDirection();
|
||||||
|
BlockPos localPos = pos.subtract(anchor);
|
||||||
|
this.superglue.add(Pair.of(localPos, direction));
|
||||||
|
glueToRemove.add(entity);
|
||||||
|
}
|
||||||
|
|
||||||
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> pair) {
|
public void add(BlockPos pos, Pair<BlockInfo, TileEntity> pair) {
|
||||||
BlockInfo captured = pair.getKey();
|
BlockInfo captured = pair.getKey();
|
||||||
BlockPos localPos = pos.subtract(anchor);
|
BlockPos localPos = pos.subtract(anchor);
|
||||||
|
@ -402,6 +427,13 @@ public abstract class Contraption {
|
||||||
getActors().add(MutablePair.of(info, context));
|
getActors().add(MutablePair.of(info, context));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
superglue.clear();
|
||||||
|
nbt.getList("Superglue", 10).forEach(c -> {
|
||||||
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
|
superglue.add(Pair.of(NBTUtil.readBlockPos(comp.getCompound("Pos")),
|
||||||
|
Direction.byIndex(comp.getByte("Direction"))));
|
||||||
|
});
|
||||||
|
|
||||||
storage.clear();
|
storage.clear();
|
||||||
nbt.getList("Storage", 10).forEach(c -> {
|
nbt.getList("Storage", 10).forEach(c -> {
|
||||||
CompoundNBT comp = (CompoundNBT) c;
|
CompoundNBT comp = (CompoundNBT) c;
|
||||||
|
@ -440,6 +472,14 @@ public abstract class Contraption {
|
||||||
actorsNBT.add(compound);
|
actorsNBT.add(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ListNBT superglueNBT = new ListNBT();
|
||||||
|
for (Pair<BlockPos, Direction> glueEntry : superglue) {
|
||||||
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
c.put("Pos", NBTUtil.writeBlockPos(glueEntry.getKey()));
|
||||||
|
c.putByte("Direction", (byte) glueEntry.getValue().getIndex());
|
||||||
|
superglueNBT.add(c);
|
||||||
|
}
|
||||||
|
|
||||||
ListNBT storageNBT = new ListNBT();
|
ListNBT storageNBT = new ListNBT();
|
||||||
for (BlockPos pos : storage.keySet()) {
|
for (BlockPos pos : storage.keySet()) {
|
||||||
CompoundNBT c = new CompoundNBT();
|
CompoundNBT c = new CompoundNBT();
|
||||||
|
@ -453,6 +493,7 @@ public abstract class Contraption {
|
||||||
|
|
||||||
nbt.put("Blocks", blocksNBT);
|
nbt.put("Blocks", blocksNBT);
|
||||||
nbt.put("Actors", actorsNBT);
|
nbt.put("Actors", actorsNBT);
|
||||||
|
nbt.put("Superglue", superglueNBT);
|
||||||
nbt.put("Storage", storageNBT);
|
nbt.put("Storage", storageNBT);
|
||||||
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
|
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||||
nbt.putBoolean("Stalled", stalled);
|
nbt.putBoolean("Stalled", stalled);
|
||||||
|
@ -466,11 +507,7 @@ public abstract class Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isFrozen() {
|
public static boolean isFrozen() {
|
||||||
return AllConfigs.SERVER.control.freezePistonConstructs.get();
|
return AllConfigs.SERVER.control.freezeContraptions.get();
|
||||||
}
|
|
||||||
|
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
|
||||||
disassemble(world, offset, rotation, (pos, state) -> false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset) {
|
||||||
|
@ -479,6 +516,8 @@ public abstract class Contraption {
|
||||||
|
|
||||||
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
public void removeBlocksFromWorld(IWorld world, BlockPos offset, BiPredicate<BlockPos, BlockState> customRemoval) {
|
||||||
storage.values().forEach(MountedStorage::empty);
|
storage.values().forEach(MountedStorage::empty);
|
||||||
|
glueToRemove.forEach(SuperGlueEntity::remove);
|
||||||
|
|
||||||
for (boolean brittles : Iterate.trueAndFalse) {
|
for (boolean brittles : Iterate.trueAndFalse) {
|
||||||
for (BlockInfo block : blocks.values()) {
|
for (BlockInfo block : blocks.values()) {
|
||||||
if (brittles != BlockMovementTraits.isBrittle(block.state))
|
if (brittles != BlockMovementTraits.isBrittle(block.state))
|
||||||
|
@ -496,7 +535,11 @@ public abstract class Contraption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation,
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
|
addBlocksToWorld(world, offset, rotation, (pos, state) -> false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation,
|
||||||
BiPredicate<BlockPos, BlockState> customPlacement) {
|
BiPredicate<BlockPos, BlockState> customPlacement) {
|
||||||
stop(world);
|
stop(world);
|
||||||
|
|
||||||
|
@ -558,10 +601,21 @@ public abstract class Contraption {
|
||||||
mountedStorage.fill(tileEntity);
|
mountedStorage.fill(tileEntity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Pair<BlockPos, Direction> pair : superglue) {
|
||||||
|
BlockPos targetPos = transform.apply(pair.getKey());
|
||||||
|
Direction targetFacing = transform.transformFacing(pair.getValue());
|
||||||
|
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, targetPos, targetFacing);
|
||||||
|
if (entity.onValidSurface()) {
|
||||||
|
if (!world.isRemote)
|
||||||
|
world.addEntity(entity);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initActors(World world) {
|
public void initActors(World world) {
|
||||||
|
|
|
@ -427,7 +427,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
||||||
if (getContraption() != null) {
|
if (getContraption() != null) {
|
||||||
BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5));
|
BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5));
|
||||||
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
||||||
getContraption().disassemble(world, offset, rotation);
|
getContraption().addBlocksToWorld(world, offset, rotation);
|
||||||
preventMovedEntitiesFromGettingStuck();
|
preventMovedEntitiesFromGettingStuck();
|
||||||
}
|
}
|
||||||
remove();
|
remove();
|
||||||
|
|
|
@ -162,14 +162,14 @@ public class StructureTransform {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Axis transformAxis(Axis axisIn) {
|
public Axis transformAxis(Axis axisIn) {
|
||||||
Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn);
|
Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn);
|
||||||
facing = transformFacing(facing);
|
facing = transformFacing(facing);
|
||||||
Axis axis = facing.getAxis();
|
Axis axis = facing.getAxis();
|
||||||
return axis;
|
return axis;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Direction transformFacing(Direction facing) {
|
public Direction transformFacing(Direction facing) {
|
||||||
for (int i = 0; i < rotation.ordinal(); i++)
|
for (int i = 0; i < rotation.ordinal(); i++)
|
||||||
facing = facing.rotateAround(rotationAxis);
|
facing = facing.rotateAround(rotationAxis);
|
||||||
return facing;
|
return facing;
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.packet.SimplePacketBase;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.network.NetworkEvent.Context;
|
||||||
|
|
||||||
|
public class GlueEffectPacket extends SimplePacketBase {
|
||||||
|
|
||||||
|
private BlockPos pos;
|
||||||
|
private Direction direction;
|
||||||
|
private boolean fullBlock;
|
||||||
|
|
||||||
|
public GlueEffectPacket(BlockPos pos, Direction direction, boolean fullBlock) {
|
||||||
|
this.pos = pos;
|
||||||
|
this.direction = direction;
|
||||||
|
this.fullBlock = fullBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlueEffectPacket(PacketBuffer buffer) {
|
||||||
|
pos = buffer.readBlockPos();
|
||||||
|
direction = Direction.byIndex(buffer.readByte());
|
||||||
|
fullBlock = buffer.readBoolean();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void write(PacketBuffer buffer) {
|
||||||
|
buffer.writeBlockPos(pos);
|
||||||
|
buffer.writeByte(direction.getIndex());
|
||||||
|
buffer.writeBoolean(fullBlock);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void handle(Supplier<Context> context) {
|
||||||
|
context.get().enqueueWork(() -> DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
if (!mc.player.getPosition().withinDistance(pos, 100))
|
||||||
|
return;
|
||||||
|
SuperGlueItem.spawnParticles(mc.world, pos, direction, fullBlock);
|
||||||
|
}));
|
||||||
|
context.get().setPacketHandled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,390 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.Validate;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllEntities;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.AllSoundEvents;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.entity.player.ClientPlayerEntity;
|
||||||
|
import net.minecraft.client.world.ClientWorld;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntitySize;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.MoverType;
|
||||||
|
import net.minecraft.entity.Pose;
|
||||||
|
import net.minecraft.entity.effect.LightningBoltEntity;
|
||||||
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.network.IPacket;
|
||||||
|
import net.minecraft.network.PacketBuffer;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.DamageSource;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
|
import net.minecraft.util.Rotation;
|
||||||
|
import net.minecraft.util.SoundEvents;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.RayTraceResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
import net.minecraftforge.fml.DistExecutor;
|
||||||
|
import net.minecraftforge.fml.common.registry.IEntityAdditionalSpawnData;
|
||||||
|
import net.minecraftforge.fml.network.NetworkHooks;
|
||||||
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
|
public class SuperGlueEntity extends Entity implements IEntityAdditionalSpawnData {
|
||||||
|
|
||||||
|
private int validationTimer;
|
||||||
|
protected BlockPos hangingPosition;
|
||||||
|
protected Direction facingDirection = Direction.SOUTH;
|
||||||
|
|
||||||
|
public SuperGlueEntity(EntityType<?> type, World world) {
|
||||||
|
super(type, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SuperGlueEntity(World world, BlockPos pos, Direction direction) {
|
||||||
|
this(AllEntities.SUPER_GLUE.type, world);
|
||||||
|
hangingPosition = pos;
|
||||||
|
facingDirection = direction;
|
||||||
|
updateFacingWithBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void registerData() {}
|
||||||
|
|
||||||
|
public int getWidthPixels() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHeightPixels() {
|
||||||
|
return 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onBroken(@Nullable Entity breaker) {
|
||||||
|
playSound(SoundEvents.ENTITY_SLIME_SQUISH_SMALL, 1.0F, 1.0F);
|
||||||
|
if (onValidSurface()) {
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> this),
|
||||||
|
new GlueEffectPacket(getHangingPosition(), getFacingDirection().getOpposite(), false));
|
||||||
|
playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.5F);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void playPlaceSound() {
|
||||||
|
playSound(AllSoundEvents.SLIME_ADDED.get(), 0.5F, 0.75F);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateFacingWithBoundingBox() {
|
||||||
|
Validate.notNull(getFacingDirection());
|
||||||
|
if (getFacingDirection().getAxis().isHorizontal()) {
|
||||||
|
this.rotationPitch = 0.0F;
|
||||||
|
this.rotationYaw = getFacingDirection().getHorizontalIndex() * 90;
|
||||||
|
} else {
|
||||||
|
this.rotationPitch = -90 * getFacingDirection().getAxisDirection().getOffset();
|
||||||
|
this.rotationYaw = 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.prevRotationPitch = this.rotationPitch;
|
||||||
|
this.prevRotationYaw = this.rotationYaw;
|
||||||
|
this.updateBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateBoundingBox() {
|
||||||
|
if (this.getFacingDirection() != null) {
|
||||||
|
this.posX =
|
||||||
|
(double) this.hangingPosition.getX() + 0.5 - (double) this.getFacingDirection().getXOffset() * 0.5;
|
||||||
|
this.posY =
|
||||||
|
(double) this.hangingPosition.getY() + 0.5 - (double) this.getFacingDirection().getYOffset() * 0.5;
|
||||||
|
this.posZ =
|
||||||
|
(double) this.hangingPosition.getZ() + 0.5 - (double) this.getFacingDirection().getZOffset() * 0.5;
|
||||||
|
double d1 = (double) this.getWidthPixels();
|
||||||
|
double d2 = (double) this.getHeightPixels();
|
||||||
|
double d3 = (double) this.getWidthPixels();
|
||||||
|
Axis axis = this.getFacingDirection().getAxis();
|
||||||
|
double depth = 2 - 1 / 128f;
|
||||||
|
|
||||||
|
switch (axis) {
|
||||||
|
case X:
|
||||||
|
d1 = depth;
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
d2 = depth;
|
||||||
|
break;
|
||||||
|
case Z:
|
||||||
|
d3 = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
d1 = d1 / 32.0D;
|
||||||
|
d2 = d2 / 32.0D;
|
||||||
|
d3 = d3 / 32.0D;
|
||||||
|
this.setBoundingBox(new AxisAlignedBB(this.posX - d1, this.posY - d2, this.posZ - d3, this.posX + d1,
|
||||||
|
this.posY + d2, this.posZ + d3));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tick() {
|
||||||
|
this.prevPosX = this.posX;
|
||||||
|
this.prevPosY = this.posY;
|
||||||
|
this.prevPosZ = this.posZ;
|
||||||
|
if (this.validationTimer++ == 10 && !this.world.isRemote) {
|
||||||
|
this.validationTimer = 0;
|
||||||
|
if (isAlive() && !this.onValidSurface()) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean onValidSurface() {
|
||||||
|
BlockPos pos = hangingPosition;
|
||||||
|
BlockPos pos2 = hangingPosition.offset(getFacingDirection().getOpposite());
|
||||||
|
if (!world.isAreaLoaded(pos, 0) || !world.isAreaLoaded(pos2, 0))
|
||||||
|
return true;
|
||||||
|
if (world.isAirBlock(pos) && world.isAirBlock(pos2))
|
||||||
|
return false;
|
||||||
|
return world.getEntitiesInAABBexcluding(this, getBoundingBox(), e -> e instanceof SuperGlueEntity).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canBeCollidedWith() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hitByEntity(Entity entity) {
|
||||||
|
return entity instanceof PlayerEntity
|
||||||
|
? attackEntityFrom(DamageSource.causePlayerDamage((PlayerEntity) entity), 0)
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Direction getHorizontalFacing() {
|
||||||
|
return this.getFacingDirection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean attackEntityFrom(DamageSource source, float amount) {
|
||||||
|
if (this.isInvulnerableTo(source))
|
||||||
|
return false;
|
||||||
|
if (isAlive() && !world.isRemote) {
|
||||||
|
remove();
|
||||||
|
markVelocityChanged();
|
||||||
|
onBroken(source.getTrueSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void move(MoverType typeIn, Vec3d pos) {
|
||||||
|
if (!world.isRemote && isAlive() && pos.lengthSquared() > 0.0D) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addVelocity(double x, double y, double z) {
|
||||||
|
if (!world.isRemote && isAlive() && x * x + y * y + z * z > 0.0D) {
|
||||||
|
remove();
|
||||||
|
onBroken(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getEyeHeight(Pose poseIn, EntitySize sizeIn) {
|
||||||
|
return 0.0F;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getPickedResult(RayTraceResult target) {
|
||||||
|
return AllItems.SUPER_GLUE.asStack();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public int getBrightnessForRender() {
|
||||||
|
BlockPos blockpos = hangingPosition;
|
||||||
|
BlockPos blockpos2 = blockpos.offset(this.getFacingDirection().getOpposite());
|
||||||
|
|
||||||
|
PlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand())
|
||||||
|
|| AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand());
|
||||||
|
boolean visible = world.isAirBlock(blockpos) || world.isAirBlock(blockpos2);
|
||||||
|
|
||||||
|
int minLight = holdingGlue && !visible ? 8 : 0;
|
||||||
|
int light = this.world.isBlockPresent(blockpos) ? this.world.getCombinedLight(blockpos, minLight) : 15;
|
||||||
|
int light2 = this.world.isBlockPresent(blockpos2) ? this.world.getCombinedLight(blockpos2, minLight) : 15;
|
||||||
|
|
||||||
|
return Math.max(light, light2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void applyEntityCollision(Entity entityIn) {
|
||||||
|
super.applyEntityCollision(entityIn);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean processInitialInteract(PlayerEntity player, Hand hand) {
|
||||||
|
DistExecutor.runWhenOn(Dist.CLIENT, () -> () -> {
|
||||||
|
triggerPlaceBlock(player, hand);
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
private void triggerPlaceBlock(PlayerEntity player, Hand hand) {
|
||||||
|
if (player instanceof ClientPlayerEntity && player.world instanceof ClientWorld) {
|
||||||
|
ClientPlayerEntity cPlayer = (ClientPlayerEntity) player;
|
||||||
|
Minecraft mc = Minecraft.getInstance();
|
||||||
|
RayTraceResult ray =
|
||||||
|
cPlayer.pick(mc.playerController.getBlockReachDistance(), mc.getRenderPartialTicks(), false);
|
||||||
|
if (ray instanceof BlockRayTraceResult) {
|
||||||
|
for (Hand handIn : Hand.values()) {
|
||||||
|
ItemStack itemstack = cPlayer.getHeldItem(handIn);
|
||||||
|
int countBefore = itemstack.getCount();
|
||||||
|
ActionResultType actionResultType = mc.playerController.func_217292_a(cPlayer,
|
||||||
|
(ClientWorld) cPlayer.world, handIn, (BlockRayTraceResult) ray);
|
||||||
|
if (actionResultType == ActionResultType.SUCCESS) {
|
||||||
|
cPlayer.swingArm(handIn);
|
||||||
|
if (!itemstack.isEmpty()
|
||||||
|
&& (itemstack.getCount() != countBefore || mc.playerController.isInCreativeMode()))
|
||||||
|
mc.gameRenderer.itemRenderer.resetEquippedProgress(handIn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeAdditional(CompoundNBT compound) {
|
||||||
|
compound.putByte("Facing", (byte) this.getFacingDirection().getIndex());
|
||||||
|
BlockPos blockpos = this.getHangingPosition();
|
||||||
|
compound.putInt("TileX", blockpos.getX());
|
||||||
|
compound.putInt("TileY", blockpos.getY());
|
||||||
|
compound.putInt("TileZ", blockpos.getZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readAdditional(CompoundNBT compound) {
|
||||||
|
this.hangingPosition =
|
||||||
|
new BlockPos(compound.getInt("TileX"), compound.getInt("TileY"), compound.getInt("TileZ"));
|
||||||
|
this.facingDirection = Direction.byIndex(compound.getByte("Facing"));
|
||||||
|
updateFacingWithBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemEntity entityDropItem(ItemStack stack, float offsetY) {
|
||||||
|
ItemEntity itementity =
|
||||||
|
new ItemEntity(this.world, this.posX + (double) ((float) this.getFacingDirection().getXOffset() * 0.15F),
|
||||||
|
this.posY + (double) offsetY,
|
||||||
|
this.posZ + (double) ((float) this.getFacingDirection().getZOffset() * 0.15F), stack);
|
||||||
|
itementity.setDefaultPickupDelay();
|
||||||
|
this.world.addEntity(itementity);
|
||||||
|
return itementity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldSetPosAfterLoading() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPosition(double x, double y, double z) {
|
||||||
|
hangingPosition = new BlockPos(x, y, z);
|
||||||
|
updateBoundingBox();
|
||||||
|
isAirBorne = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getRotatedYaw(Rotation transformRotation) {
|
||||||
|
if (this.getFacingDirection().getAxis() != Direction.Axis.Y) {
|
||||||
|
switch (transformRotation) {
|
||||||
|
case CLOCKWISE_180:
|
||||||
|
this.facingDirection = this.getFacingDirection().getOpposite();
|
||||||
|
break;
|
||||||
|
case COUNTERCLOCKWISE_90:
|
||||||
|
this.facingDirection = this.getFacingDirection().rotateYCCW();
|
||||||
|
break;
|
||||||
|
case CLOCKWISE_90:
|
||||||
|
this.facingDirection = this.getFacingDirection().rotateY();
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float f = MathHelper.wrapDegrees(this.rotationYaw);
|
||||||
|
switch (transformRotation) {
|
||||||
|
case CLOCKWISE_180:
|
||||||
|
return f + 180.0F;
|
||||||
|
case COUNTERCLOCKWISE_90:
|
||||||
|
return f + 90.0F;
|
||||||
|
case CLOCKWISE_90:
|
||||||
|
return f + 270.0F;
|
||||||
|
default:
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public BlockPos getHangingPosition() {
|
||||||
|
return this.hangingPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getMirroredYaw(Mirror transformMirror) {
|
||||||
|
return this.getRotatedYaw(transformMirror.toRotation(this.getFacingDirection()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getAttachedDirection(BlockPos pos) {
|
||||||
|
return !pos.equals(hangingPosition) ? getFacingDirection() : getFacingDirection().getOpposite();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStruckByLightning(LightningBoltEntity lightningBolt) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void recalculateSize() {}
|
||||||
|
|
||||||
|
public static EntityType.Builder<?> build(EntityType.Builder<?> builder) {
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
EntityType.Builder<SuperGlueEntity> entityBuilder = (EntityType.Builder<SuperGlueEntity>) builder;
|
||||||
|
return entityBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPacket<?> createSpawnPacket() {
|
||||||
|
return NetworkHooks.getEntitySpawningPacket(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSpawnData(PacketBuffer buffer) {
|
||||||
|
CompoundNBT compound = new CompoundNBT();
|
||||||
|
writeAdditional(compound);
|
||||||
|
buffer.writeCompoundTag(compound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readSpawnData(PacketBuffer additionalData) {
|
||||||
|
readAdditional(additionalData.readCompoundTag());
|
||||||
|
}
|
||||||
|
|
||||||
|
public Direction getFacingDirection() {
|
||||||
|
return facingDirection;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.AllPackets;
|
||||||
|
import com.simibubi.create.foundation.utility.RayTraceWorld;
|
||||||
|
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.BlockRayTraceResult;
|
||||||
|
import net.minecraft.util.math.RayTraceContext;
|
||||||
|
import net.minecraft.util.math.RayTraceResult.Type;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.IWorld;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.event.world.BlockEvent.EntityPlaceEvent;
|
||||||
|
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
|
||||||
|
import net.minecraftforge.fml.network.PacketDistributor;
|
||||||
|
|
||||||
|
@EventBusSubscriber
|
||||||
|
public class SuperGlueHandler {
|
||||||
|
|
||||||
|
public static Map<Direction, SuperGlueEntity> gatherGlue(IWorld world, BlockPos pos) {
|
||||||
|
List<SuperGlueEntity> entities = world.getEntitiesWithinAABB(SuperGlueEntity.class, new AxisAlignedBB(pos));
|
||||||
|
Map<Direction, SuperGlueEntity> map = new HashMap<>();
|
||||||
|
for (SuperGlueEntity entity : entities)
|
||||||
|
map.put(entity.getAttachedDirection(pos), entity);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SubscribeEvent
|
||||||
|
public static void glueListensForBlockPlacement(EntityPlaceEvent event) {
|
||||||
|
IWorld world = event.getWorld();
|
||||||
|
Entity entity = event.getEntity();
|
||||||
|
BlockPos pos = event.getPos();
|
||||||
|
|
||||||
|
if (entity == null || world == null || pos == null)
|
||||||
|
return;
|
||||||
|
if (event.isCanceled())
|
||||||
|
return;
|
||||||
|
if (world.isRemote())
|
||||||
|
return;
|
||||||
|
|
||||||
|
Map<Direction, SuperGlueEntity> gatheredGlue = gatherGlue(world, pos);
|
||||||
|
for (Direction direction : gatheredGlue.keySet())
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity),
|
||||||
|
new GlueEffectPacket(pos, direction, true));
|
||||||
|
|
||||||
|
if (entity instanceof PlayerEntity)
|
||||||
|
glueInOffHandAppliesOnBlockPlace(event, pos, (PlayerEntity) entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void glueInOffHandAppliesOnBlockPlace(EntityPlaceEvent event, BlockPos pos, PlayerEntity placer) {
|
||||||
|
ItemStack itemstack = placer.getHeldItemOffhand();
|
||||||
|
if (!AllItems.SUPER_GLUE.typeOf(itemstack))
|
||||||
|
return;
|
||||||
|
|
||||||
|
double distance = placer.getAttribute(PlayerEntity.REACH_DISTANCE).getValue();
|
||||||
|
Vec3d start = placer.getEyePosition(1);
|
||||||
|
Vec3d look = placer.getLook(1);
|
||||||
|
Vec3d end = start.add(look.x * distance, look.y * distance, look.z * distance);
|
||||||
|
World world = placer.world;
|
||||||
|
|
||||||
|
RayTraceWorld rayTraceWorld =
|
||||||
|
new RayTraceWorld(world, (p, state) -> p.equals(pos) ? Blocks.AIR.getDefaultState() : state);
|
||||||
|
BlockRayTraceResult ray = rayTraceWorld.rayTraceBlocks(new RayTraceContext(start, end,
|
||||||
|
RayTraceContext.BlockMode.OUTLINE, RayTraceContext.FluidMode.NONE, placer));
|
||||||
|
|
||||||
|
Direction face = ray.getFace();
|
||||||
|
if (ray == null || face == null || ray.getType() == Type.MISS)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ray.getPos().offset(face).equals(pos)) {
|
||||||
|
event.setCanceled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, ray.getPos(), face.getOpposite());
|
||||||
|
CompoundNBT compoundnbt = itemstack.getTag();
|
||||||
|
if (compoundnbt != null)
|
||||||
|
EntityType.applyItemNBT(world, placer, entity, compoundnbt);
|
||||||
|
|
||||||
|
if (entity.onValidSurface()) {
|
||||||
|
if (!world.isRemote) {
|
||||||
|
entity.playPlaceSound();
|
||||||
|
world.addEntity(entity);
|
||||||
|
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(() -> entity),
|
||||||
|
new GlueEffectPacket(ray.getPos(), face, true));
|
||||||
|
}
|
||||||
|
itemstack.damageItem(1, placer, SuperGlueItem::onBroken);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.Item;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.ItemUseContext;
|
||||||
|
import net.minecraft.item.Items;
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
import net.minecraft.particles.ItemParticleData;
|
||||||
|
import net.minecraft.particles.ParticleTypes;
|
||||||
|
import net.minecraft.util.ActionResultType;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
public class SuperGlueItem extends Item {
|
||||||
|
|
||||||
|
public SuperGlueItem(Properties properties) {
|
||||||
|
super(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDamageable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxDamage(ItemStack stack) {
|
||||||
|
return 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemStackLimit(ItemStack stack) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResultType onItemUse(ItemUseContext context) {
|
||||||
|
BlockPos blockpos = context.getPos();
|
||||||
|
Direction direction = context.getFace();
|
||||||
|
BlockPos blockpos1 = blockpos.offset(direction);
|
||||||
|
PlayerEntity playerentity = context.getPlayer();
|
||||||
|
ItemStack itemstack = context.getItem();
|
||||||
|
|
||||||
|
if (playerentity != null && !this.canPlace(playerentity, direction, itemstack, blockpos1))
|
||||||
|
return ActionResultType.FAIL;
|
||||||
|
|
||||||
|
World world = context.getWorld();
|
||||||
|
SuperGlueEntity entity = new SuperGlueEntity(world, blockpos1, direction);
|
||||||
|
CompoundNBT compoundnbt = itemstack.getTag();
|
||||||
|
if (compoundnbt != null)
|
||||||
|
EntityType.applyItemNBT(world, playerentity, entity, compoundnbt);
|
||||||
|
|
||||||
|
if (!entity.onValidSurface())
|
||||||
|
return ActionResultType.FAIL;
|
||||||
|
|
||||||
|
if (!world.isRemote) {
|
||||||
|
entity.playPlaceSound();
|
||||||
|
world.addEntity(entity);
|
||||||
|
}
|
||||||
|
itemstack.damageItem(1, playerentity, SuperGlueItem::onBroken);
|
||||||
|
|
||||||
|
return ActionResultType.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onBroken(PlayerEntity player) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean canPlace(PlayerEntity entity, Direction facing, ItemStack stack, BlockPos pos) {
|
||||||
|
return !World.isOutsideBuildHeight(pos) && entity.canPlayerEdit(pos, facing, stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public static void spawnParticles(World world, BlockPos pos, Direction direction, boolean fullBlock) {
|
||||||
|
Vec3d vec = new Vec3d(direction.getDirectionVec());
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(vec);
|
||||||
|
Vec3d facePos = VecHelper.getCenterOf(pos).add(vec.scale(.5f));
|
||||||
|
|
||||||
|
float distance = fullBlock ? 1f : .25f + .25f * (world.rand.nextFloat() - .5f);
|
||||||
|
plane = plane.scale(distance);
|
||||||
|
ItemStack stack = new ItemStack(Items.SLIME_BALL);
|
||||||
|
|
||||||
|
for (int i = fullBlock ? 40 : 15; i > 0; i--) {
|
||||||
|
Vec3d offset = VecHelper.rotate(plane, 360 * world.rand.nextFloat(), direction.getAxis());
|
||||||
|
Vec3d motion = offset.normalize().scale(1 / 16f);
|
||||||
|
if (fullBlock)
|
||||||
|
offset = new Vec3d(MathHelper.clamp(offset.x, -.5, .5), MathHelper.clamp(offset.y, -.5, .5),
|
||||||
|
MathHelper.clamp(offset.z, -.5, .5));
|
||||||
|
Vec3d particlePos = facePos.add(offset);
|
||||||
|
world.addParticle(new ItemParticleData(ParticleTypes.ITEM, stack), particlePos.x, particlePos.y,
|
||||||
|
particlePos.z, motion.x, motion.y, motion.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package com.simibubi.create.modules.contraptions.components.contraptions.glue;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.simibubi.create.AllItems;
|
||||||
|
import com.simibubi.create.Create;
|
||||||
|
import com.simibubi.create.config.AllConfigs;
|
||||||
|
import com.simibubi.create.foundation.utility.AngleHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.VecHelper;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraft.client.renderer.BufferBuilder;
|
||||||
|
import net.minecraft.client.renderer.Tessellator;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||||
|
import net.minecraft.client.renderer.entity.EntityRendererManager;
|
||||||
|
import net.minecraft.client.renderer.model.PositionTextureVertex;
|
||||||
|
import net.minecraft.client.renderer.model.TexturedQuad;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.util.Direction;
|
||||||
|
import net.minecraft.util.Direction.Axis;
|
||||||
|
import net.minecraft.util.ResourceLocation;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
public class SuperGlueRenderer extends EntityRenderer<SuperGlueEntity> {
|
||||||
|
|
||||||
|
private ResourceLocation regular = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png");
|
||||||
|
private ResourceLocation ghostly = new ResourceLocation(Create.ID, "textures/entity/super_glue/ghostly.png");
|
||||||
|
|
||||||
|
private TexturedQuad quad1;
|
||||||
|
private TexturedQuad quad2;
|
||||||
|
|
||||||
|
public SuperGlueRenderer(EntityRendererManager renderManager) {
|
||||||
|
super(renderManager);
|
||||||
|
initQuads();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResourceLocation getEntityTexture(SuperGlueEntity entity) {
|
||||||
|
return isVisible(entity) ? regular : ghostly;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doRender(SuperGlueEntity entity, double x, double y, double z, float entityYaw, float partialTicks) {
|
||||||
|
Direction facing = entity.getFacingDirection();
|
||||||
|
PlayerEntity player = Minecraft.getInstance().player;
|
||||||
|
|
||||||
|
boolean visible = isVisible(entity);
|
||||||
|
boolean holdingGlue = AllItems.SUPER_GLUE.typeOf(player.getHeldItemMainhand())
|
||||||
|
|| AllItems.SUPER_GLUE.typeOf(player.getHeldItemOffhand());
|
||||||
|
holdingGlue = holdingGlue && AllConfigs.CLIENT.showHiddenSuperGlue.get();
|
||||||
|
|
||||||
|
if (!visible && !holdingGlue)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GlStateManager.pushMatrix();
|
||||||
|
GlStateManager.translated(x, y, z);
|
||||||
|
GlStateManager.rotated(AngleHelper.horizontalAngle(facing), 0, 1, 0);
|
||||||
|
GlStateManager.rotated(AngleHelper.verticalAngle(facing), 1, 0, 0);
|
||||||
|
|
||||||
|
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
|
||||||
|
bindEntityTexture(entity);
|
||||||
|
|
||||||
|
if (!visible) {
|
||||||
|
GlStateManager.color4f(1, 1, 1, 0.375f);
|
||||||
|
GlStateManager.enableBlend();
|
||||||
|
GlStateManager.disableDepthTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
quad1.draw(buffer, 1);
|
||||||
|
quad2.draw(buffer, 1);
|
||||||
|
|
||||||
|
GlStateManager.disableBlend();
|
||||||
|
GlStateManager.enableDepthTest();
|
||||||
|
GlStateManager.color4f(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
|
GlStateManager.popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isVisible(SuperGlueEntity entity) {
|
||||||
|
if (!entity.isAlive())
|
||||||
|
return false;
|
||||||
|
BlockPos pos = entity.hangingPosition;
|
||||||
|
BlockPos pos2 = pos.offset(entity.getFacingDirection().getOpposite());
|
||||||
|
return entity.world.isAirBlock(pos) != entity.world.isAirBlock(pos2);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initQuads() {
|
||||||
|
Vec3d diff = new Vec3d(Direction.SOUTH.getDirectionVec());
|
||||||
|
Vec3d extension = diff.normalize().scale(1 / 32f - 1 / 128f);
|
||||||
|
Vec3d plane = VecHelper.planeByNormal(diff);
|
||||||
|
Axis axis = Direction.getFacingFromVector(diff.x, diff.y, diff.z).getAxis();
|
||||||
|
|
||||||
|
Vec3d start = Vec3d.ZERO.subtract(extension);
|
||||||
|
Vec3d end = Vec3d.ZERO.add(extension);
|
||||||
|
|
||||||
|
plane = plane.scale(1 / 2f);
|
||||||
|
Vec3d a1 = plane.add(start);
|
||||||
|
Vec3d b1 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a2 = plane.add(start);
|
||||||
|
Vec3d b2 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a3 = plane.add(start);
|
||||||
|
Vec3d b3 = plane.add(end);
|
||||||
|
plane = VecHelper.rotate(plane, -90, axis);
|
||||||
|
Vec3d a4 = plane.add(start);
|
||||||
|
Vec3d b4 = plane.add(end);
|
||||||
|
|
||||||
|
PositionTextureVertex v11 = new PositionTextureVertex(a1, 1, 0);
|
||||||
|
PositionTextureVertex v12 = new PositionTextureVertex(a2, 1, 1);
|
||||||
|
PositionTextureVertex v13 = new PositionTextureVertex(a3, 0, 1);
|
||||||
|
PositionTextureVertex v14 = new PositionTextureVertex(a4, 0, 0);
|
||||||
|
|
||||||
|
PositionTextureVertex v21 = new PositionTextureVertex(b1, 1, 0);
|
||||||
|
PositionTextureVertex v22 = new PositionTextureVertex(b2, 1, 1);
|
||||||
|
PositionTextureVertex v23 = new PositionTextureVertex(b3, 0, 1);
|
||||||
|
PositionTextureVertex v24 = new PositionTextureVertex(b4, 0, 0);
|
||||||
|
|
||||||
|
quad1 = new TexturedQuad(new PositionTextureVertex[] { v14, v11, v12, v13 }, 0, 0, 16, 16, 16, 16);
|
||||||
|
quad2 = new TexturedQuad(new PositionTextureVertex[] { v21, v24, v23, v22 }, 0, 0, 16, 16, 16, 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -89,8 +89,8 @@ public class MountedContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
super.disassemble(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,8 +170,8 @@ public class PistonContraption extends Contraption {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||||
super.disassemble(world, offset, rotation, (pos, state) -> {
|
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> {
|
||||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||||
BlockState pistonState = world.getBlockState(pistonPos);
|
BlockState pistonState = world.getBlockState(pistonPos);
|
||||||
TileEntity te = world.getTileEntity(pistonPos);
|
TileEntity te = world.getTileEntity(pistonPos);
|
||||||
|
|
|
@ -6,6 +6,7 @@ import static com.simibubi.create.modules.contraptions.base.HorizontalKineticBlo
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -137,8 +138,8 @@ public class ConnectedInputHandler {
|
||||||
if (controllerPos1.equals(controllerPos2)) {
|
if (controllerPos1.equals(controllerPos2)) {
|
||||||
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
||||||
|
|
||||||
Set<BlockPos> positions = controller.input.data.stream().map(l -> controllerPos1.add(l))
|
Set<BlockPos> positions =
|
||||||
.collect(Collectors.toSet());
|
controller.input.data.stream().map(l -> controllerPos1.add(l)).collect(Collectors.toSet());
|
||||||
List<BlockPos> frontier = new LinkedList<>();
|
List<BlockPos> frontier = new LinkedList<>();
|
||||||
List<BlockPos> splitGroup = new ArrayList<>();
|
List<BlockPos> splitGroup = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -198,8 +199,7 @@ public class ConnectedInputHandler {
|
||||||
|
|
||||||
crafter1.input.data.forEach(offset -> {
|
crafter1.input.data.forEach(offset -> {
|
||||||
BlockPos connectedPos = crafter1.getPos().add(offset);
|
BlockPos connectedPos = crafter1.getPos().add(offset);
|
||||||
modifyAndUpdate(world, connectedPos, input -> {
|
modifyAndUpdate(world, connectedPos, input -> {});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
crafter2.input.data.forEach(offset -> {
|
crafter2.input.data.forEach(offset -> {
|
||||||
|
@ -229,7 +229,7 @@ public class ConnectedInputHandler {
|
||||||
|
|
||||||
public static class ConnectedInput {
|
public static class ConnectedInput {
|
||||||
boolean isController;
|
boolean isController;
|
||||||
List<BlockPos> data = new ArrayList<>();
|
List<BlockPos> data = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
public ConnectedInput() {
|
public ConnectedInput() {
|
||||||
isController = true;
|
isController = true;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import com.simibubi.create.modules.contraptions.components.crafter.MechanicalCra
|
||||||
import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
import com.simibubi.create.modules.contraptions.components.crafter.RecipeGridHandler.GroupedItems;
|
||||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.entity.item.ItemEntity;
|
import net.minecraft.entity.item.ItemEntity;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
@ -357,8 +358,10 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void eject() {
|
public void eject() {
|
||||||
Vec3d ejectPos = VecHelper.getCenterOf(pos)
|
BlockState blockState = getBlockState();
|
||||||
.add(new Vec3d(getBlockState().get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f));
|
boolean present = AllBlocks.MECHANICAL_CRAFTER.typeOf(blockState);
|
||||||
|
Vec3d vec = present ? new Vec3d(blockState.get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f) : Vec3d.ZERO;
|
||||||
|
Vec3d ejectPos = VecHelper.getCenterOf(pos).add(vec);
|
||||||
groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack));
|
groupedItems.grid.forEach((pair, stack) -> dropItem(ejectPos, stack));
|
||||||
if (!inventory.getStackInSlot(0).isEmpty())
|
if (!inventory.getStackInSlot(0).isEmpty())
|
||||||
dropItem(ejectPos, inventory.getStackInSlot(0));
|
dropItem(ejectPos, inventory.getStackInSlot(0));
|
||||||
|
|
|
@ -71,7 +71,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
||||||
if (!canConnect(world, firstPulley, pos))
|
if (!canConnect(world, firstPulley, pos))
|
||||||
return ActionResultType.FAIL;
|
return ActionResultType.FAIL;
|
||||||
|
|
||||||
if (!firstPulley.equals(pos)) {
|
if (firstPulley != null && !firstPulley.equals(pos)) {
|
||||||
createBelts(world, firstPulley, pos);
|
createBelts(world, firstPulley, pos);
|
||||||
|
|
||||||
if (!context.getPlayer().isCreative())
|
if (!context.getPlayer().isCreative())
|
||||||
|
|
|
@ -166,7 +166,6 @@ public class SchematicHologram {
|
||||||
drawBuffer(bufferBuilder);
|
drawBuffer(bufferBuilder);
|
||||||
GlStateManager.popMatrix();
|
GlStateManager.popMatrix();
|
||||||
}
|
}
|
||||||
GlStateManager.disableAlphaTest();
|
|
||||||
GlStateManager.disableBlend();
|
GlStateManager.disableBlend();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@
|
||||||
"item.create.sand_paper": "Sand Paper",
|
"item.create.sand_paper": "Sand Paper",
|
||||||
"item.create.red_sand_paper": "Red Sand Paper",
|
"item.create.red_sand_paper": "Red Sand Paper",
|
||||||
"item.create.super_glue": "Super Glue",
|
"item.create.super_glue": "Super Glue",
|
||||||
"item.create.antioxidant": "Antioxidant Spray",
|
|
||||||
|
|
||||||
"item.create.brass_ingot": "Brass Ingot",
|
"item.create.brass_ingot": "Brass Ingot",
|
||||||
"item.create.brass_sheet": "Brass Sheets",
|
"item.create.brass_sheet": "Brass Sheets",
|
||||||
|
@ -258,6 +257,10 @@
|
||||||
"block.create.creative_crate": "Schematicannon Creatifier",
|
"block.create.creative_crate": "Schematicannon Creatifier",
|
||||||
|
|
||||||
"block.create.cocoa_log": "Cocoa Jungle Log",
|
"block.create.cocoa_log": "Cocoa Jungle Log",
|
||||||
|
|
||||||
|
"entity.create.contraption": "Moving Contraption",
|
||||||
|
"entity.create.stationary_contraption": "Stationary Contraption",
|
||||||
|
"entity.create.super_glue": "Superglue",
|
||||||
|
|
||||||
"_comment": "-------------------------] UI & MESSAGES [------------------------------------------------",
|
"_comment": "-------------------------] UI & MESSAGES [------------------------------------------------",
|
||||||
|
|
||||||
|
@ -1136,6 +1139,13 @@
|
||||||
"tool.create.sand_paper.tooltip.summary": "A rough paper that can be used to _polish_ _materials_. Can be automatically applied using the Deployer.",
|
"tool.create.sand_paper.tooltip.summary": "A rough paper that can be used to _polish_ _materials_. Can be automatically applied using the Deployer.",
|
||||||
"tool.create.sand_paper.tooltip.condition1": "When Used",
|
"tool.create.sand_paper.tooltip.condition1": "When Used",
|
||||||
"tool.create.sand_paper.tooltip.behaviour1": "Applies polish to items held in the _offhand_ or lying on the _floor_ when _looking_ _at_ _them_",
|
"tool.create.sand_paper.tooltip.behaviour1": "Applies polish to items held in the _offhand_ or lying on the _floor_ when _looking_ _at_ _them_",
|
||||||
|
|
||||||
|
"item.create.super_glue.tooltip": "SUPER GLUE",
|
||||||
|
"item.create.super_glue.tooltip.summary": "Glue a block to another, and they will forever be inseparable.",
|
||||||
|
"item.create.super_glue.tooltip.condition1": "When Used",
|
||||||
|
"item.create.super_glue.tooltip.behaviour1": "Makes the _clicked_ _face_ of a block _sticky_. Blocks attached to sticky faces will be _dragged_ _along_ when moved by _mechanical_ _pistons_, _bearings_ and other controllers.",
|
||||||
|
"item.create.super_glue.tooltip.condition2": "When Held in Offhand",
|
||||||
|
"item.create.super_glue.tooltip.behaviour2": "_Automatically_ _attaches_ blocks placed from the main hand to the _side_ they were _placed_ _against._",
|
||||||
|
|
||||||
"item.create.refined_radiance.tooltip": "REFINED RADIANCE",
|
"item.create.refined_radiance.tooltip": "REFINED RADIANCE",
|
||||||
"item.create.refined_radiance.tooltip.summary": "A Chromatic material forged from _absorbed_ _light_.",
|
"item.create.refined_radiance.tooltip.summary": "A Chromatic material forged from _absorbed_ _light_.",
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 367 B |
Binary file not shown.
After Width: | Height: | Size: 588 B |
Binary file not shown.
Before Width: | Height: | Size: 393 B After Width: | Height: | Size: 394 B |
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"type": "crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
"AS",
|
||||||
|
"NA"
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"A": {
|
||||||
|
"tag": "forge:slimeballs"
|
||||||
|
},
|
||||||
|
"S": {
|
||||||
|
"tag": "forge:plates/iron"
|
||||||
|
},
|
||||||
|
"N": {
|
||||||
|
"tag": "forge:nuggets/iron"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "create:super_glue",
|
||||||
|
"count": 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue