mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-24 14:06:42 +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.modules.contraptions.components.contraptions.ContraptionEntity;
|
||||
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.EntityClassification;
|
||||
|
@ -23,6 +25,8 @@ public enum AllEntities {
|
|||
ContraptionEntity::build),
|
||||
STATIONARY_CONTRAPTION(ContraptionEntity::new, EntityClassification.MISC, 30, 40,
|
||||
false, ContraptionEntity::build),
|
||||
SUPER_GLUE(SuperGlueEntity::new, EntityClassification.MISC, 30, Integer.MAX_VALUE, false, SuperGlueEntity::build),
|
||||
|
||||
;
|
||||
|
||||
private IFactory<?> factory;
|
||||
|
@ -62,8 +66,8 @@ public enum AllEntities {
|
|||
|
||||
@OnlyIn(value = Dist.CLIENT)
|
||||
public static void registerRenderers() {
|
||||
// RenderingRegistry.registerEntityRenderingHandler(CardboardBoxEntity.class, CardboardBoxEntityRenderer::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.contraptions.GogglesItem;
|
||||
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.gearbox.VerticalGearboxItem;
|
||||
import com.simibubi.create.modules.curiosities.ChromaticCompoundCubeItem;
|
||||
|
@ -76,7 +77,7 @@ public enum AllItems {
|
|||
BRASS_INGOT(new TaggedItem().withForgeTags("ingots/brass")),
|
||||
|
||||
FLOUR,
|
||||
DOUGH,
|
||||
DOUGH,
|
||||
OBSIDIAN_DUST,
|
||||
ROSE_QUARTZ,
|
||||
POLISHED_ROSE_QUARTZ,
|
||||
|
@ -93,8 +94,7 @@ public enum AllItems {
|
|||
WHISK,
|
||||
BRASS_HAND,
|
||||
SLOT_COVER,
|
||||
SUPER_GLUE,
|
||||
ANTIOXIDANT,
|
||||
SUPER_GLUE(SuperGlueItem::new),
|
||||
SAND_PAPER(SandPaperItem::new),
|
||||
RED_SAND_PAPER(SandPaperItem::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.modules.contraptions.components.contraptions.CancelPlayerFallPacket;
|
||||
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.curiosities.symmetry.SymmetryEffectPacket;
|
||||
import com.simibubi.create.modules.curiosities.zapper.ZapperBeamPacket;
|
||||
|
@ -51,6 +52,7 @@ public enum AllPackets {
|
|||
CONFIGURE_CONFIG(ConfigureConfigPacket.class, ConfigureConfigPacket::new),
|
||||
CONTRAPTION_STALL(ContraptionStallPacket.class, ContraptionStallPacket::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 ConfigBool rainbowDebug =
|
||||
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
|
||||
public String getName() {
|
||||
|
|
|
@ -5,9 +5,9 @@ public class CDamageControl extends ConfigBase {
|
|||
public ConfigBool freezeCrushing = b(false, "freezeCrushing", Comments.freezeCrushing);
|
||||
public ConfigBool freezeExtractors = b(false, "freezeExtractors", Comments.freezeExtractors);
|
||||
public ConfigBool freezeInWorldProcessing = b(false, "freezeInWorldProcessing", Comments.freezeInWorldProcessing);
|
||||
public ConfigBool freezeRotationPropagator = b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
||||
public ConfigBool freezeBearingConstructs = b(false, "freezeBearingConstructs", Comments.freezeBearingConstructs);
|
||||
public ConfigBool freezePistonConstructs = b(false, "freezePistonConstructs", Comments.freezePistonConstructs);
|
||||
public ConfigBool freezeRotationPropagator =
|
||||
b(false, "freezeRotationPropagator", Comments.freezeRotationPropagator);
|
||||
public ConfigBool freezeContraptions = b(false, "freezeContraptions", Comments.freezeContraptions);
|
||||
|
||||
@Override
|
||||
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 freezeRotationPropagator =
|
||||
"Pauses rotation logic altogether - Use if crash mentions RotationPropagators.";
|
||||
static String freezeBearingConstructs = "In case Mechanical Bearings turned against you.";
|
||||
static String freezePistonConstructs = "In case Mechanical Pistons pushed it too far.";
|
||||
static String freezeContraptions = "In case Moving contraptions pushed it too far.";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -71,6 +71,8 @@ public class ValueBoxRenderer {
|
|||
}
|
||||
|
||||
box.render(highlighted);
|
||||
GlStateManager.disableBlend();
|
||||
GlStateManager.disableAlphaTest();
|
||||
}
|
||||
|
||||
public static void renderText(ValueBox box, FontRenderer font, String text) {
|
||||
|
|
|
@ -60,6 +60,7 @@ public class ScrollValueRenderer {
|
|||
}
|
||||
} else
|
||||
render(world, pos, face, behaviour, highlight);
|
||||
|
||||
TessellatorHelper.cleanUpAfterDrawing();
|
||||
GlStateManager.enableAlphaTest();
|
||||
GlStateManager.blendFunc(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA);
|
||||
|
|
|
@ -67,10 +67,9 @@ public class ScreenElementRenderer {
|
|||
BlockRendererDispatcher blockRenderer = mc.getBlockRendererDispatcher();
|
||||
IBakedModel modelToRender = null;
|
||||
BlockState blockToRender = null;
|
||||
boolean stateMode = transformsAndModel == null;
|
||||
boolean fire = false;
|
||||
|
||||
if (stateMode) {
|
||||
if (transformsAndModel == null) {
|
||||
blockToRender = transformsAndState.get();
|
||||
fire = (blockToRender.getBlock() instanceof FireBlock);
|
||||
modelToRender = blockRenderer.getModelForState(blockToRender);
|
||||
|
@ -81,7 +80,6 @@ public class ScreenElementRenderer {
|
|||
GlStateManager.scaled(50, -50, 50);
|
||||
mc.getTextureManager().bindTexture(AtlasTexture.LOCATION_BLOCKS_TEXTURE);
|
||||
|
||||
|
||||
GlStateManager.pushMatrix();
|
||||
if (fire) {
|
||||
blockRenderer.renderBlockBrightness(blockToRender, 1);
|
||||
|
@ -97,7 +95,7 @@ public class ScreenElementRenderer {
|
|||
}
|
||||
GlStateManager.popMatrix();
|
||||
|
||||
if (stateMode && !blockToRender.getFluidState().isEmpty()) {
|
||||
if (blockToRender != null && !blockToRender.getFluidState().isEmpty()) {
|
||||
RenderHelper.disableStandardItemLighting();
|
||||
Tessellator tessellator = Tessellator.getInstance();
|
||||
BufferBuilder bufferbuilder = tessellator.getBuffer();
|
||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.util.math.BlockPos;
|
|||
public class Iterate {
|
||||
|
||||
public static final boolean[] trueAndFalse = { true, false };
|
||||
public static final int[] zeroAndOne = { 1, -1 };
|
||||
public static final int[] positiveAndNegative = { 1, -1 };
|
||||
public static final Direction[] directions = Direction.values();
|
||||
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() {
|
||||
GlStateManager.popAttributes();
|
||||
GlStateManager.popMatrix();
|
||||
GlStateManager.disableAlphaTest();
|
||||
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.components.contraptions.chassis.AbstractChassisBlock;
|
||||
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.PistonState;
|
||||
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.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.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.redstone.ContactBlock;
|
||||
import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock;
|
||||
|
@ -74,6 +76,7 @@ public abstract class Contraption {
|
|||
public List<MutablePair<BlockInfo, MovementContext>> actors;
|
||||
public CombinedInvWrapper inventory;
|
||||
public List<TileEntity> customRenderTEs;
|
||||
public Set<Pair<BlockPos, Direction>> superglue;
|
||||
|
||||
public AxisAlignedBB bounds;
|
||||
public boolean stalled;
|
||||
|
@ -83,13 +86,16 @@ public abstract class Contraption {
|
|||
protected BlockPos anchor;
|
||||
|
||||
List<BlockPos> renderOrder;
|
||||
List<SuperGlueEntity> glueToRemove;
|
||||
|
||||
public Contraption() {
|
||||
blocks = new HashMap<>();
|
||||
storage = new HashMap<>();
|
||||
actors = new ArrayList<>();
|
||||
superglue = new HashSet<>();
|
||||
renderOrder = new ArrayList<>();
|
||||
customRenderTEs = new ArrayList<>();
|
||||
glueToRemove = new ArrayList<>();
|
||||
}
|
||||
|
||||
public Set<BlockPos> getColliders(World world, Direction movementDirection) {
|
||||
|
@ -242,6 +248,8 @@ public abstract class Contraption {
|
|||
frontier.add(otherPartPos);
|
||||
}
|
||||
|
||||
Map<Direction, SuperGlueEntity> superglue = SuperGlueHandler.gatherGlue(world, pos);
|
||||
|
||||
// Slime blocks drag adjacent blocks if possible
|
||||
boolean isSlimeBlock = state.getBlock() instanceof SlimeBlock;
|
||||
for (Direction offset : Direction.values()) {
|
||||
|
@ -254,9 +262,18 @@ public abstract class Contraption {
|
|||
return false;
|
||||
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);
|
||||
|
||||
if (faceHasGlue)
|
||||
addGlue(superglue.get(offset));
|
||||
}
|
||||
|
||||
add(pos, capture(world, pos));
|
||||
|
@ -325,6 +342,14 @@ public abstract class Contraption {
|
|||
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) {
|
||||
BlockInfo captured = pair.getKey();
|
||||
BlockPos localPos = pos.subtract(anchor);
|
||||
|
@ -402,6 +427,13 @@ public abstract class Contraption {
|
|||
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();
|
||||
nbt.getList("Storage", 10).forEach(c -> {
|
||||
CompoundNBT comp = (CompoundNBT) c;
|
||||
|
@ -440,6 +472,14 @@ public abstract class Contraption {
|
|||
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();
|
||||
for (BlockPos pos : storage.keySet()) {
|
||||
CompoundNBT c = new CompoundNBT();
|
||||
|
@ -453,6 +493,7 @@ public abstract class Contraption {
|
|||
|
||||
nbt.put("Blocks", blocksNBT);
|
||||
nbt.put("Actors", actorsNBT);
|
||||
nbt.put("Superglue", superglueNBT);
|
||||
nbt.put("Storage", storageNBT);
|
||||
nbt.put("Anchor", NBTUtil.writeBlockPos(anchor));
|
||||
nbt.putBoolean("Stalled", stalled);
|
||||
|
@ -466,11 +507,7 @@ public abstract class Contraption {
|
|||
}
|
||||
|
||||
public static boolean isFrozen() {
|
||||
return AllConfigs.SERVER.control.freezePistonConstructs.get();
|
||||
}
|
||||
|
||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
||||
disassemble(world, offset, rotation, (pos, state) -> false);
|
||||
return AllConfigs.SERVER.control.freezeContraptions.get();
|
||||
}
|
||||
|
||||
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) {
|
||||
storage.values().forEach(MountedStorage::empty);
|
||||
glueToRemove.forEach(SuperGlueEntity::remove);
|
||||
|
||||
for (boolean brittles : Iterate.trueAndFalse) {
|
||||
for (BlockInfo block : blocks.values()) {
|
||||
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) {
|
||||
stop(world);
|
||||
|
||||
|
@ -558,10 +601,21 @@ public abstract class Contraption {
|
|||
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) {
|
||||
|
|
|
@ -427,7 +427,7 @@ public class ContraptionEntity extends Entity implements IEntityAdditionalSpawnD
|
|||
if (getContraption() != null) {
|
||||
BlockPos offset = new BlockPos(getPositionVec().add(.5, .5, .5));
|
||||
Vec3d rotation = new Vec3d(getRoll(1), getYaw(1), getPitch(1));
|
||||
getContraption().disassemble(world, offset, rotation);
|
||||
getContraption().addBlocksToWorld(world, offset, rotation);
|
||||
preventMovedEntitiesFromGettingStuck();
|
||||
}
|
||||
remove();
|
||||
|
|
|
@ -162,14 +162,14 @@ public class StructureTransform {
|
|||
return state;
|
||||
}
|
||||
|
||||
protected Axis transformAxis(Axis axisIn) {
|
||||
public Axis transformAxis(Axis axisIn) {
|
||||
Direction facing = Direction.getFacingFromAxis(AxisDirection.POSITIVE, axisIn);
|
||||
facing = transformFacing(facing);
|
||||
Axis axis = facing.getAxis();
|
||||
return axis;
|
||||
}
|
||||
|
||||
protected Direction transformFacing(Direction facing) {
|
||||
public Direction transformFacing(Direction facing) {
|
||||
for (int i = 0; i < rotation.ordinal(); i++)
|
||||
facing = facing.rotateAround(rotationAxis);
|
||||
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
|
||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
||||
super.disassemble(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
||||
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> AllBlocks.MINECART_ANCHOR.typeOf(state));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -170,8 +170,8 @@ public class PistonContraption extends Contraption {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void disassemble(World world, BlockPos offset, Vec3d rotation) {
|
||||
super.disassemble(world, offset, rotation, (pos, state) -> {
|
||||
public void addBlocksToWorld(World world, BlockPos offset, Vec3d rotation) {
|
||||
super.addBlocksToWorld(world, offset, rotation, (pos, state) -> {
|
||||
BlockPos pistonPos = anchor.offset(orientation, -1);
|
||||
BlockState pistonState = world.getBlockState(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.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
@ -137,8 +138,8 @@ public class ConnectedInputHandler {
|
|||
if (controllerPos1.equals(controllerPos2)) {
|
||||
MechanicalCrafterTileEntity controller = CrafterHelper.getCrafter(world, controllerPos1);
|
||||
|
||||
Set<BlockPos> positions = controller.input.data.stream().map(l -> controllerPos1.add(l))
|
||||
.collect(Collectors.toSet());
|
||||
Set<BlockPos> positions =
|
||||
controller.input.data.stream().map(l -> controllerPos1.add(l)).collect(Collectors.toSet());
|
||||
List<BlockPos> frontier = new LinkedList<>();
|
||||
List<BlockPos> splitGroup = new ArrayList<>();
|
||||
|
||||
|
@ -198,8 +199,7 @@ public class ConnectedInputHandler {
|
|||
|
||||
crafter1.input.data.forEach(offset -> {
|
||||
BlockPos connectedPos = crafter1.getPos().add(offset);
|
||||
modifyAndUpdate(world, connectedPos, input -> {
|
||||
});
|
||||
modifyAndUpdate(world, connectedPos, input -> {});
|
||||
});
|
||||
|
||||
crafter2.input.data.forEach(offset -> {
|
||||
|
@ -229,7 +229,7 @@ public class ConnectedInputHandler {
|
|||
|
||||
public static class ConnectedInput {
|
||||
boolean isController;
|
||||
List<BlockPos> data = new ArrayList<>();
|
||||
List<BlockPos> data = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
public ConnectedInput() {
|
||||
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.relays.belt.BeltTileEntity;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.entity.item.ItemEntity;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
|
@ -357,8 +358,10 @@ public class MechanicalCrafterTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
public void eject() {
|
||||
Vec3d ejectPos = VecHelper.getCenterOf(pos)
|
||||
.add(new Vec3d(getBlockState().get(HORIZONTAL_FACING).getDirectionVec()).scale(.75f));
|
||||
BlockState blockState = getBlockState();
|
||||
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));
|
||||
if (!inventory.getStackInSlot(0).isEmpty())
|
||||
dropItem(ejectPos, inventory.getStackInSlot(0));
|
||||
|
|
|
@ -71,7 +71,7 @@ public class BeltConnectorItem extends BlockItem implements IAddedByOther {
|
|||
if (!canConnect(world, firstPulley, pos))
|
||||
return ActionResultType.FAIL;
|
||||
|
||||
if (!firstPulley.equals(pos)) {
|
||||
if (firstPulley != null && !firstPulley.equals(pos)) {
|
||||
createBelts(world, firstPulley, pos);
|
||||
|
||||
if (!context.getPlayer().isCreative())
|
||||
|
|
|
@ -166,7 +166,6 @@ public class SchematicHologram {
|
|||
drawBuffer(bufferBuilder);
|
||||
GlStateManager.popMatrix();
|
||||
}
|
||||
GlStateManager.disableAlphaTest();
|
||||
GlStateManager.disableBlend();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
"item.create.sand_paper": "Sand Paper",
|
||||
"item.create.red_sand_paper": "Red Sand Paper",
|
||||
"item.create.super_glue": "Super Glue",
|
||||
"item.create.antioxidant": "Antioxidant Spray",
|
||||
|
||||
"item.create.brass_ingot": "Brass Ingot",
|
||||
"item.create.brass_sheet": "Brass Sheets",
|
||||
|
@ -258,6 +257,10 @@
|
|||
"block.create.creative_crate": "Schematicannon Creatifier",
|
||||
|
||||
"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 [------------------------------------------------",
|
||||
|
||||
|
@ -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.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_",
|
||||
|
||||
"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.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