From a0734dffaf1a6b2db1af47f38c7dbdabaa94d558 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Wed, 28 Aug 2019 16:54:27 +0200 Subject: [PATCH] Extractors and Linked Extractors - Added extractors for dropping items from an inventory - Further generalized Wireless Redstone actors - Made the crushing wheel more dramatic - Stationary Drills will drop items more carefully --- .../com/simibubi/create/AllTileEntities.java | 9 +- .../create/foundation/utility/VecHelper.java | 7 + .../CrushingWheelControllerTileEntity.java | 27 +-- .../receivers/DrillTileEntity.java | 50 ++++-- .../modules/logistics/IHaveWireless.java | 2 + .../logistics/block/ExtractorBlock.java | 50 ++++++ .../logistics/block/ExtractorTileEntity.java | 56 ++++++ .../logistics/block/IBlockWithFrequency.java | 127 +++++++++++++ .../modules/logistics/block/IExtractor.java | 170 ++++++++++++++++++ .../logistics/block/LinkedExtractorBlock.java | 83 ++++++++- .../block/LinkedExtractorTileEntity.java | 78 ++++++++ .../logistics/block/LinkedTileEntity.java | 86 +++++++++ ...rer.java => LinkedTileEntityRenderer.java} | 35 ++-- .../logistics/block/RedstoneBridgeBlock.java | 112 ++---------- .../block/RedstoneBridgeTileEntity.java | 82 +-------- 15 files changed, 754 insertions(+), 220 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntity.java rename src/main/java/com/simibubi/create/modules/logistics/block/{RedstoneBridgeTileEntityRenderer.java => LinkedTileEntityRenderer.java} (76%) diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 1df016a73..032c24a73 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -22,9 +22,11 @@ import com.simibubi.create.modules.contraptions.relays.GearboxTileEntityRenderer import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntity; import com.simibubi.create.modules.contraptions.relays.GearshifterTileEntityRenderer; import com.simibubi.create.modules.economy.ShopShelfTileEntity; +import com.simibubi.create.modules.logistics.block.ExtractorTileEntity; import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity; +import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntity; import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity; -import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntityRenderer; +import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer; import com.simibubi.create.modules.logistics.block.StockswitchTileEntity; import com.simibubi.create.modules.schematics.block.SchematicTableTileEntity; import com.simibubi.create.modules.schematics.block.SchematicannonRenderer; @@ -66,6 +68,8 @@ public enum AllTileEntities { REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE), STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH), FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), + EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR), + LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR), // Economy SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF), @@ -110,7 +114,8 @@ public enum AllTileEntities { bind(DrillTileEntity.class, new KineticTileEntityRenderer()); bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer()); bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer()); - bind(RedstoneBridgeTileEntity.class, new RedstoneBridgeTileEntityRenderer()); + bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer()); + bind(LinkedExtractorTileEntity.class, new LinkedTileEntityRenderer()); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index 5bf835917..25e52117b 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -1,5 +1,7 @@ package com.simibubi.create.foundation.utility; +import java.util.Random; + import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; @@ -29,4 +31,9 @@ public class VecHelper { return new Vec3d(pos).add(.5f, .5f, .5f); } + public static Vec3d offsetRandomly(Vec3d vec, Random r, float radius) { + return new Vec3d(vec.x + (r.nextFloat() - .5f) * 2 * radius, vec.y + (r.nextFloat() - .5f) * 2 * radius, + vec.z + (r.nextFloat() - .5f) * 2 * radius); + } + } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelControllerTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelControllerTileEntity.java index f0c6e8f2a..7b89c4c01 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelControllerTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/CrushingWheelControllerTileEntity.java @@ -60,15 +60,15 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen Inventory inventory = new Inventory(); NonNullList stacks = NonNullList.withSize(10, ItemStack.EMPTY); ItemStackHelper.loadAllItems(nbt, stacks); - + for (int slot = 0; slot < stacks.size(); slot++) inventory.setInventorySlotContents(slot, stacks.get(slot)); - inventory.processingDuration = nbt.getInt("ProcessingTime"); - inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe"); + inventory.processingDuration = nbt.getInt("ProcessingTime"); + inventory.appliedRecipe = nbt.getBoolean("AppliedRecipe"); return inventory; } - + public ItemStackHandler getItems() { return (ItemStackHandler) inv; } @@ -97,14 +97,14 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen float speed = crushingspeed / 2.5f; if (!hasEntity()) { - - float processingSpeed = speed / (!contents.appliedRecipe? contents.getStackInSlot(0).getCount() : 1); + + float processingSpeed = speed / (!contents.appliedRecipe ? contents.getStackInSlot(0).getCount() : 1); contents.processingDuration -= processingSpeed; spawnParticles(contents.getStackInSlot(0)); if (world.isRemote) return; - + if (contents.processingDuration < 20 && !contents.appliedRecipe) { applyRecipe(); contents.appliedRecipe = true; @@ -167,8 +167,9 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen particleData = new ItemParticleData(ParticleTypes.ITEM, stack); Random r = world.rand; - world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(), - pos.getZ() + r.nextFloat(), 0, 0, 0); + for (int i = 0; i < 4; i++) + world.addParticle(particleData, pos.getX() + r.nextFloat(), pos.getY() + r.nextFloat(), + pos.getZ() + r.nextFloat(), 0, 0, 0); } private void applyRecipe() { @@ -178,16 +179,16 @@ public class CrushingWheelControllerTileEntity extends SyncedTileEntity implemen if (recipe.isPresent()) { int rolls = contents.getStackInSlot(0).getCount(); contents.clear(); - + for (int roll = 0; roll < rolls; roll++) { List rolledResults = recipe.get().rollResults(); - + for (int i = 0; i < rolledResults.size(); i++) { ItemStack stack = rolledResults.get(i); - + for (int slot = 0; slot < contents.getSizeInventory(); slot++) { stack = contents.getItems().insertItem(slot, stack, false); - + if (stack.isEmpty()) break; } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java index 85831a94f..9bd575091 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/receivers/DrillTileEntity.java @@ -3,20 +3,29 @@ package com.simibubi.create.modules.contraptions.receivers; import java.util.concurrent.atomic.AtomicInteger; import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.base.KineticTileEntity; import net.minecraft.block.AirBlock; +import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.fluid.IFluidState; +import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.GameRules; +import net.minecraft.world.server.ServerWorld; public class DrillTileEntity extends KineticTileEntity implements ITickableTileEntity { private static final AtomicInteger NEXT_DRILL_ID = new AtomicInteger(); - + private int ticksUntilNextProgress; private int destroyProgress; private int drillId = -NEXT_DRILL_ID.incrementAndGet(); @@ -34,21 +43,21 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE public void destroyNextTick() { ticksUntilNextProgress = 1; } - + @Override public CompoundNBT write(CompoundNBT compound) { compound.putInt("Progress", destroyProgress); compound.putInt("NextTick", ticksUntilNextProgress); return super.write(compound); } - + @Override public void read(CompoundNBT compound) { destroyProgress = compound.getInt("Progress"); ticksUntilNextProgress = compound.getInt("NextTick"); super.read(compound); } - + @Override public void remove() { if (!world.isRemote && destroyProgress != 0) { @@ -64,33 +73,52 @@ public class DrillTileEntity extends KineticTileEntity implements ITickableTileE return; if (speed == 0) return; - + if (ticksUntilNextProgress < 0) return; if (ticksUntilNextProgress-- > 0) return; - + BlockPos posToBreak = pos.offset(getBlockState().get(BlockStateProperties.FACING)); BlockState stateToBreak = world.getBlockState(posToBreak); float blockHardness = stateToBreak.getBlockHardness(world, posToBreak); - - if (stateToBreak.getMaterial().isLiquid() || stateToBreak.getBlock() instanceof AirBlock || blockHardness == -1) { + + if (stateToBreak.getMaterial().isLiquid() || stateToBreak.getBlock() instanceof AirBlock + || blockHardness == -1) { destroyProgress = 0; world.sendBlockBreakProgress(drillId, posToBreak, -1); return; } - + float breakSpeed = Math.abs(speed / 100f); destroyProgress += MathHelper.clamp((int) (breakSpeed / blockHardness), 1, 10 - destroyProgress); if (destroyProgress >= 10) { - world.destroyBlock(posToBreak, true); + + IFluidState ifluidstate = world.getFluidState(pos); + world.playEvent(2001, posToBreak, Block.getStateId(stateToBreak)); + TileEntity tileentity = stateToBreak.hasTileEntity() ? world.getTileEntity(posToBreak) : null; + Vec3d vec = VecHelper.offsetRandomly(VecHelper.getCenterOf(posToBreak), world.rand, .125f); + + Block.getDrops(stateToBreak, (ServerWorld) world, posToBreak, tileentity).forEach((stack) -> { + if (!stack.isEmpty() && world.getGameRules().getBoolean(GameRules.DO_TILE_DROPS) + && !world.restoringBlockSnapshots) { + ItemEntity itementity = new ItemEntity(world, vec.x, vec.y, vec.z, stack); + itementity.setDefaultPickupDelay(); + itementity.setMotion(Vec3d.ZERO); + world.addEntity(itementity); + } + }); + + stateToBreak.spawnAdditionalDrops(world, posToBreak, ItemStack.EMPTY); + world.setBlockState(posToBreak, ifluidstate.getBlockState(), 3); + destroyProgress = 0; ticksUntilNextProgress = -1; world.sendBlockBreakProgress(drillId, posToBreak, -1); return; } - + ticksUntilNextProgress = (int) (blockHardness / breakSpeed); world.sendBlockBreakProgress(drillId, posToBreak, (int) destroyProgress); } diff --git a/src/main/java/com/simibubi/create/modules/logistics/IHaveWireless.java b/src/main/java/com/simibubi/create/modules/logistics/IHaveWireless.java index e4ea2c2c3..41009a790 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/IHaveWireless.java +++ b/src/main/java/com/simibubi/create/modules/logistics/IHaveWireless.java @@ -2,6 +2,7 @@ package com.simibubi.create.modules.logistics; import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency; +import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -9,6 +10,7 @@ public interface IHaveWireless { public Frequency getFrequencyFirst(); public Frequency getFrequencyLast(); + public void setFrequency(boolean first, ItemStack stack); public World getWorld(); public BlockPos getPos(); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorBlock.java index 3726453d4..7d5291ce2 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorBlock.java @@ -4,16 +4,21 @@ import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.block.HorizontalBlock; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.state.BooleanProperty; import net.minecraft.state.StateContainer.Builder; import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; +import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; import net.minecraft.world.IBlockReader; +import net.minecraft.world.IWorldReader; import net.minecraft.world.World; public class ExtractorBlock extends HorizontalBlock { @@ -34,6 +39,22 @@ public class ExtractorBlock extends HorizontalBlock { super.fillStateContainer(builder); } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new ExtractorTileEntity(); + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + return false; + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { BlockState state = getDefaultState(); @@ -47,6 +68,31 @@ public class ExtractorBlock extends HorizontalBlock { return state.with(POWERED, Boolean.valueOf(context.getWorld().isBlockPowered(context.getPos()))); } + @Override + public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { + updateObservedInventory(state, worldIn, pos); + } + + @Override + public void onNeighborChange(BlockState state, IWorldReader world, BlockPos pos, BlockPos neighbor) { + if (world.isRemote()) + return; + if (!isObserving(state, pos, neighbor)) + return; + updateObservedInventory(state, world, pos); + } + + private void updateObservedInventory(BlockState state, IWorldReader world, BlockPos pos) { + IExtractor extractor = (IExtractor) world.getTileEntity(pos); + if (extractor == null) + return; + extractor.neighborChanged(); + } + + private boolean isObserving(BlockState state, BlockPos pos, BlockPos observing) { + return observing.equals(pos.offset(state.get(HORIZONTAL_FACING))); + } + @Override public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { @@ -56,6 +102,10 @@ public class ExtractorBlock extends HorizontalBlock { boolean previouslyPowered = state.get(POWERED); if (previouslyPowered != worldIn.isBlockPowered(pos)) { worldIn.setBlockState(pos, state.cycle(POWERED), 2); + IExtractor extractor = (IExtractor) worldIn.getTileEntity(pos); + if (extractor == null) + return; + extractor.setLocked(!previouslyPowered); } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java new file mode 100644 index 000000000..6b71925cb --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java @@ -0,0 +1,56 @@ +package com.simibubi.create.modules.logistics.block; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.SyncedTileEntity; + +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; + +public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, ITickableTileEntity { + + private State state; + private int cooldown; + private LazyOptional inventory; + + public ExtractorTileEntity() { + super(AllTileEntities.EXTRACTOR.type); + state = State.WAITING_FOR_ITEM; + inventory = LazyOptional.empty(); + } + + @Override + public State getState() { + return state; + } + + @Override + public void setState(State state) { + if (state == State.ON_COOLDOWN) + cooldown = EXTRACTOR_COOLDOWN; + this.state = state; + } + + @Override + public int tickCooldown() { + return cooldown--; + } + + @Override + public BlockPos getInventoryPos() { + return getPos().offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING)); + } + + @Override + public LazyOptional getInventory() { + return inventory; + } + + @Override + public void setInventory(LazyOptional inventory) { + this.inventory = inventory; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java new file mode 100644 index 000000000..d5bc08d25 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java @@ -0,0 +1,127 @@ +package com.simibubi.create.modules.logistics.block; + +import org.apache.commons.lang3.tuple.Pair; + +import com.mojang.blaze3d.platform.GlStateManager; +import com.simibubi.create.foundation.utility.TessellatorHelper; +import com.simibubi.create.modules.logistics.IHaveWireless; + +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +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.client.event.DrawBlockHighlightEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod.EventBusSubscriber; + +@EventBusSubscriber(value = Dist.CLIENT) +public interface IBlockWithFrequency { + + public Pair getFrequencyItemPositions(BlockState state); + public Direction getFrequencyItemFacing(BlockState state); + + public default float getItemHitboxScale() { + return 2 / 16f; + } + + public default boolean handleActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, + Hand handIn, BlockRayTraceResult hit) { + TileEntity te = worldIn.getTileEntity(pos); + if (te == null || !(te instanceof IHaveWireless)) + return false; + + IHaveWireless actor = (IHaveWireless) te; + Pair positions = getFrequencyItemPositions(state); + ItemStack stack = player.getHeldItem(handIn); + Vec3d vec = new Vec3d(pos); + Vec3d first = positions.getLeft().add(vec); + Vec3d second = positions.getRight().add(vec); + float scale = getItemHitboxScale(); + + if (new AxisAlignedBB(first, first).grow(scale).contains(hit.getHitVec())) { + if (worldIn.isRemote) + return true; + actor.setFrequency(true, stack); + return true; + } + + if (new AxisAlignedBB(second, second).grow(scale).contains(hit.getHitVec())) { + if (worldIn.isRemote) + return true; + actor.setFrequency(false, stack); + return true; + } + + return false; + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) { + if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult)) + return; + + BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget(); + ClientWorld world = Minecraft.getInstance().world; + BlockPos pos = result.getPos(); + BlockState state = world.getBlockState(pos); + + if (!(state.getBlock() instanceof IBlockWithFrequency)) + return; + + IBlockWithFrequency freqBlock = (IBlockWithFrequency) state.getBlock(); + Pair positions = freqBlock.getFrequencyItemPositions(state); + Vec3d vec = new Vec3d(pos); + Vec3d first = positions.getLeft().add(vec); + Vec3d second = positions.getRight().add(vec); + float scale = freqBlock.getItemHitboxScale(); + + AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(scale); + AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(scale); + + TessellatorHelper.prepareForDrawing(); + GlStateManager.enableBlend(); + GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, + GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, + GlStateManager.DestFactor.ZERO); + GlStateManager.disableTexture(); + GlStateManager.depthMask(false); + GlStateManager.matrixMode(5889); + + if (firstBB.contains(result.getHitVec())) { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f); + } else { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f); + } + + if (secondBB.contains(result.getHitVec())) { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f); + } else { + GlStateManager.lineWidth(2); + WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), .5f, .5f, .2f, 1f); + } + + GlStateManager.matrixMode(5888); + GlStateManager.depthMask(true); + GlStateManager.enableTexture(); + GlStateManager.disableBlend(); + GlStateManager.lineWidth(1); + TessellatorHelper.cleanUpAfterDrawing(); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java new file mode 100644 index 000000000..4054e1986 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java @@ -0,0 +1,170 @@ +package com.simibubi.create.modules.logistics.block; + +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.block.BlockState; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.CapabilityItemHandler; +import net.minecraftforge.items.IItemHandler; + +// Its like delegation but better! +public interface IExtractor extends ITickableTileEntity { + + public static final int EXTRACTOR_COOLDOWN = 20; + public static final int EXTRACTION_COUNT = 16; + + public enum State { + WAITING_FOR_ITEM, WAITING_FOR_SPACE, RUNNING, ON_COOLDOWN, LOCKED; + } + + public State getState(); + + public void setState(State state); + + public int tickCooldown(); + + public World getWorld(); + + public BlockPos getPos(); + + public BlockPos getInventoryPos(); + + public LazyOptional getInventory(); + + public void setInventory(LazyOptional inventory); + + @Override + default void tick() { + State state = getState(); + + if (state == State.LOCKED) + return; + + if (state == State.ON_COOLDOWN) { + int cooldown = tickCooldown(); + if (cooldown <= 0) + setState(State.RUNNING); + return; + } + + boolean hasSpace = hasSpaceForExtracting(); + boolean hasInventory = getInventory().isPresent(); + ItemStack toExtract = ItemStack.EMPTY; + + if (hasSpace && hasInventory) + toExtract = extract(true); + + if (state == State.WAITING_FOR_SPACE) { + if (hasSpace) + setState(State.RUNNING); + } + + if (state == State.RUNNING) { + if (!hasSpace) { + setState(State.WAITING_FOR_SPACE); + return; + } + if (!hasInventory || toExtract.isEmpty()) { + setState(State.WAITING_FOR_ITEM); + return; + } + + extract(false); + setState(State.ON_COOLDOWN); + + return; + } + + } + + public default void setLocked(boolean locked) { + setState(locked ? State.LOCKED : State.ON_COOLDOWN); + } + + public default void neighborChanged() { + boolean hasSpace = hasSpaceForExtracting(); + boolean hasInventory = getInventory().isPresent(); + ItemStack toExtract = ItemStack.EMPTY; + + if (hasSpace && hasInventory) + toExtract = extract(true); + + if (getState() == State.WAITING_FOR_ITEM) { + if (!hasInventory) { + if (findNewInventory()) { + setState(State.RUNNING); + } + } + if (!toExtract.isEmpty()) + setState(State.RUNNING); + return; + } + } + + default boolean hasSpaceForExtracting() { + return getWorld().getEntitiesWithinAABBExcludingEntity(null, new AxisAlignedBB(getPos())).isEmpty(); + } + + default ItemStack extract(boolean simulate) { + IItemHandler inv = getInventory().orElse(null); + ItemStack extracting = ItemStack.EMPTY; + + for (int slot = 0; slot < inv.getSlots(); slot++) { + ItemStack stack = inv.extractItem(slot, EXTRACTION_COUNT - extracting.getCount(), true); + ItemStack compare = stack.copy(); + compare.setCount(extracting.getCount()); + if (!extracting.isEmpty() && !extracting.equals(compare, false)) + continue; + + if (extracting.isEmpty()) + extracting = stack.copy(); + else + extracting.grow(stack.getCount()); + + if (!simulate) + inv.extractItem(slot, stack.getCount(), false); + if (extracting.getCount() >= EXTRACTION_COUNT) + break; + } + + if (!simulate) { + World world = getWorld(); + Vec3d pos = VecHelper.getCenterOf(getPos()).add(0, -0.5f, 0); + ItemEntity entityIn = new ItemEntity(world, pos.x, pos.y, pos.z, extracting); + entityIn.setMotion(Vec3d.ZERO); + world.addEntity(entityIn); + } + + return extracting; + } + + default boolean findNewInventory() { + BlockPos invPos = getInventoryPos(); + World world = getWorld(); + + if (!world.isBlockPresent(invPos)) + return false; + BlockState invState = world.getBlockState(invPos); + + if (!invState.hasTileEntity()) + return false; + TileEntity invTE = world.getTileEntity(invPos); + + LazyOptional inventory = invTE.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY); + setInventory(inventory); + if (inventory.isPresent()) { + return true; + } + + return false; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorBlock.java index e77788e9b..a3f50baef 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorBlock.java @@ -1,31 +1,108 @@ package com.simibubi.create.modules.logistics.block; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.tuple.Pair; + +import com.simibubi.create.foundation.utility.VecHelper; + import net.minecraft.block.Block; import net.minecraft.block.BlockState; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; +import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockRenderLayer; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.IBlockReader; import net.minecraft.world.World; -public class LinkedExtractorBlock extends ExtractorBlock { +public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFrequency { + + private static final List> itemPositions = new ArrayList<>(Direction.values().length); public LinkedExtractorBlock() { super(); + cacheItemPositions(); } - + @Override public BlockRenderLayer getRenderLayer() { return BlockRenderLayer.CUTOUT; } + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new LinkedExtractorTileEntity(); + } + @Override public BlockState getStateForPlacement(BlockItemUseContext context) { return super.getStateForPlacement(context).with(POWERED, false); } - + @Override public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block blockIn, BlockPos fromPos, boolean isMoving) { } + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + return super.onBlockActivated(state, worldIn, pos, player, handIn, hit) + || handleActivated(state, worldIn, pos, player, handIn, hit); + } + + private void cacheItemPositions() { + if (!itemPositions.isEmpty()) + return; + + Vec3d first = Vec3d.ZERO; + Vec3d second = Vec3d.ZERO; + Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO); + float zFightOffset = 1 / 128f; + + for (int i = 0; i < 4; i++) { + Direction facing = Direction.byHorizontalIndex(i); + first = new Vec3d(11.5f / 16f + zFightOffset, 4f / 16f, 14f / 16f ); + second = new Vec3d(11.5f / 16f + zFightOffset, 8f / 16f, 14f / 16f); + + float angle = facing.getHorizontalAngle(); + if (facing.getAxis() == Axis.X) + angle = -angle; + + first = VecHelper.rotate(first.subtract(shift), angle, Axis.Y).add(shift); + second = VecHelper.rotate(second.subtract(shift), angle, Axis.Y).add(shift); + + itemPositions.add(Pair.of(first, second)); + } + + } + + @Override + public float getItemHitboxScale() { + return 3/32f; + } + + @Override + public Pair getFrequencyItemPositions(BlockState state) { + Direction facing = state.get(HORIZONTAL_FACING); + return itemPositions.get(facing.getHorizontalIndex()); + } + + @Override + public Direction getFrequencyItemFacing(BlockState state) { + return state.get(HORIZONTAL_FACING).rotateYCCW(); + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java new file mode 100644 index 000000000..98845da65 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java @@ -0,0 +1,78 @@ +package com.simibubi.create.modules.logistics.block; + +import static net.minecraft.state.properties.BlockStateProperties.POWERED; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.modules.logistics.IReceiveWireless; + +import net.minecraft.state.properties.BlockStateProperties; +import net.minecraft.tileentity.ITickableTileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.items.IItemHandler; + +public class LinkedExtractorTileEntity extends LinkedTileEntity + implements IReceiveWireless, ITickableTileEntity, IExtractor { + + public boolean receivedSignal; + + private State state; + private int cooldown; + private LazyOptional inventory; + + public LinkedExtractorTileEntity() { + super(AllTileEntities.LINKED_EXTRACTOR.type); + state = State.WAITING_FOR_ITEM; + inventory = LazyOptional.empty(); + } + + @Override + public void setSignal(boolean powered) { + receivedSignal = powered; + } + + @Override + public void tick() { + IExtractor.super.tick(); + if (world.isRemote) + return; + if (receivedSignal != getBlockState().get(POWERED)) { + setLocked(receivedSignal); + world.setBlockState(pos, getBlockState().cycle(POWERED)); + return; + } + } + + @Override + public State getState() { + return state; + } + + @Override + public void setState(State state) { + if (state == State.ON_COOLDOWN) + cooldown = EXTRACTOR_COOLDOWN; + this.state = state; + } + + @Override + public int tickCooldown() { + return cooldown--; + } + + @Override + public BlockPos getInventoryPos() { + return getPos().offset(getBlockState().get(BlockStateProperties.HORIZONTAL_FACING)); + } + + @Override + public LazyOptional getInventory() { + return inventory; + } + + @Override + public void setInventory(LazyOptional inventory) { + this.inventory = inventory; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntity.java new file mode 100644 index 000000000..5bb9d046a --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntity.java @@ -0,0 +1,86 @@ +package com.simibubi.create.modules.logistics.block; + +import com.simibubi.create.foundation.block.SyncedTileEntity; +import com.simibubi.create.modules.logistics.FrequencyHandler; +import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency; +import com.simibubi.create.modules.logistics.IHaveWireless; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.tileentity.TileEntityType; + +public abstract class LinkedTileEntity extends SyncedTileEntity implements IHaveWireless { + + public Frequency frequencyFirst; + public Frequency frequencyLast; + + public LinkedTileEntity(TileEntityType tileEntityTypeIn) { + super(tileEntityTypeIn); + frequencyFirst = new Frequency(ItemStack.EMPTY); + frequencyLast = new Frequency(ItemStack.EMPTY); + } + + @Override + public void onLoad() { + super.onLoad(); + if (world.isRemote) + return; + FrequencyHandler.addToNetwork(this); + } + + @Override + public void remove() { + super.remove(); + if (world.isRemote) + return; + FrequencyHandler.removeFromNetwork(this); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT())); + compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT())); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst"))); + frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast"))); + super.read(compound); + } + + @Override + public void setFrequency(boolean first, ItemStack stack) { + stack = stack.copy(); + stack.setCount(1); + ItemStack toCompare = first ? frequencyFirst.getStack() : frequencyLast.getStack(); + boolean changed = !ItemStack.areItemsEqual(stack, toCompare) + || !ItemStack.areItemStackTagsEqual(stack, toCompare); + + if (changed) + FrequencyHandler.removeFromNetwork(this); + + if (first) + frequencyFirst = new Frequency(stack); + else + frequencyLast = new Frequency(stack); + + if (!changed) + return; + + sendData(); + FrequencyHandler.addToNetwork(this); + } + + @Override + public Frequency getFrequencyFirst() { + return frequencyFirst; + } + + @Override + public Frequency getFrequencyLast() { + return frequencyLast; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java similarity index 76% rename from src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntityRenderer.java rename to src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java index c8d47e9d8..d18190fa4 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java @@ -5,72 +5,75 @@ import org.apache.commons.lang3.tuple.Pair; import com.mojang.blaze3d.platform.GlStateManager; import com.simibubi.create.foundation.utility.TessellatorHelper; +import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.ItemRenderer; import net.minecraft.client.renderer.model.IBakedModel; import net.minecraft.client.renderer.model.ItemCameraTransforms.TransformType; import net.minecraft.client.renderer.tileentity.TileEntityRenderer; import net.minecraft.item.ItemStack; -import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; @SuppressWarnings("deprecation") -public class RedstoneBridgeTileEntityRenderer extends TileEntityRenderer { +public class LinkedTileEntityRenderer extends TileEntityRenderer { @Override - public void render(RedstoneBridgeTileEntity tileEntityIn, double x, double y, double z, float partialTicks, + public void render(LinkedTileEntity tileEntityIn, double x, double y, double z, float partialTicks, int destroyStage) { super.render(tileEntityIn, x, y, z, partialTicks, destroyStage); - Direction facing = tileEntityIn.getBlockState().get(BlockStateProperties.FACING); - + BlockState state = tileEntityIn.getBlockState(); + IBlockWithFrequency block = (IBlockWithFrequency) state.getBlock(); + Direction facing = block.getFrequencyItemFacing(state); + float scale = block.getItemHitboxScale(); + TessellatorHelper.prepareForDrawing(); - Pair itemPositions = RedstoneBridgeBlock.getFrequencyItemPositions(tileEntityIn.getBlockState()); + Pair itemPositions = block.getFrequencyItemPositions(state); Vec3d first = itemPositions.getLeft(); Vec3d second = itemPositions.getRight(); BlockPos pos = tileEntityIn.getPos(); GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); - renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing); - renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing); + renderFrequencyItem(tileEntityIn.frequencyFirst.getStack(), first, facing, scale - 2/16f); + renderFrequencyItem(tileEntityIn.frequencyLast.getStack(), second, facing, scale - 2/16f); TessellatorHelper.cleanUpAfterDrawing(); } - private void renderFrequencyItem(ItemStack stack, Vec3d position, Direction facing) { + private void renderFrequencyItem(ItemStack stack, Vec3d position, Direction facing, float scaleDiff) { ItemRenderer itemRenderer = Minecraft.getInstance().getItemRenderer(); boolean vertical = facing.getAxis().isVertical(); - + IBakedModel modelWithOverrides = itemRenderer.getModelWithOverrides(stack); boolean blockItem = modelWithOverrides.isGui3d(); - + float offX = 0; float offY = vertical && !blockItem ? 0 : 0; - float offZ = !blockItem ? 1/4f : 0; + float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff : 0; if (vertical) offZ = -offZ; - + float rotX = vertical ? 90 : 0; float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0); float rotZ = vertical && facing == Direction.DOWN ? 180 : 0; if (facing.getAxis() == Axis.X) { -// offZ = -offZ; rotY = -rotY; } - + float scale = !blockItem ? .25f : .5f; + scale *= 1 + 8 * scaleDiff; GlStateManager.pushMatrix(); GlStateManager.translated(position.x, position.y, position.z); - GlStateManager.scaled(scale, scale, scale); GlStateManager.rotatef(rotZ, 0, 0, 1); GlStateManager.rotatef(rotY, 0, 1, 0); GlStateManager.rotatef(rotX, 1, 0, 0); + GlStateManager.scaled(scale, scale, scale); GlStateManager.translatef(offX, offY, offZ); itemRenderer.renderItem(stack, TransformType.FIXED); GlStateManager.popMatrix(); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeBlock.java index c7443451f..e9912af9f 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeBlock.java @@ -5,23 +5,17 @@ import java.util.List; import org.apache.commons.lang3.tuple.Pair; -import com.mojang.blaze3d.platform.GlStateManager; -import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.block.ProperDirectionalBlock; import com.simibubi.create.foundation.utility.ITooltip; import com.simibubi.create.foundation.utility.ItemDescription; import com.simibubi.create.foundation.utility.ItemDescription.Palette; -import com.simibubi.create.foundation.utility.TessellatorHelper; import com.simibubi.create.foundation.utility.TooltipHolder; import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.util.ITooltipFlag; -import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.BlockItemUseContext; import net.minecraft.item.ItemStack; @@ -33,7 +27,6 @@ import net.minecraft.util.BlockRenderLayer; import net.minecraft.util.Direction; import net.minecraft.util.Direction.Axis; import net.minecraft.util.Hand; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.Vec3d; @@ -46,12 +39,8 @@ import net.minecraft.world.IWorldReader; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.client.event.DrawBlockHighlightEvent; -import net.minecraftforge.eventbus.api.SubscribeEvent; -import net.minecraftforge.fml.common.Mod.EventBusSubscriber; -@EventBusSubscriber(value = Dist.CLIENT) -public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip { +public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITooltip, IBlockWithFrequency { public static final BooleanProperty POWERED = BlockStateProperties.POWERED; public static final BooleanProperty RECEIVER = BooleanProperty.create("receiver"); @@ -151,15 +140,12 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool @Override public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - Direction facing = state.get(FACING); - Pair positions = itemPositions.get(facing.getIndex()); - ItemStack stack = player.getHeldItem(handIn); - RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos); - - if (te == null) - return false; if (player.isSneaking()) { + RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) worldIn.getTileEntity(pos); + if (te == null) + return false; + if (!worldIn.isRemote) { Boolean wasReceiver = state.get(RECEIVER); boolean blockPowered = worldIn.isBlockPowered(pos); @@ -172,86 +158,7 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool return true; } - Vec3d vec = new Vec3d(pos); - Vec3d first = positions.getLeft().add(vec); - Vec3d second = positions.getRight().add(vec); - - if (new AxisAlignedBB(first, first).grow(2 / 16f).contains(hit.getHitVec())) { - if (worldIn.isRemote) - return true; - te.setFrequency(true, stack); - return true; - } - - if (new AxisAlignedBB(second, second).grow(2 / 16f).contains(hit.getHitVec())) { - if (worldIn.isRemote) - return true; - te.setFrequency(false, stack); - return true; - } - - return false; - } - - @SubscribeEvent - @OnlyIn(Dist.CLIENT) - public static void onDrawBlockHighlight(DrawBlockHighlightEvent event) { - if (event.getTarget() == null || !(event.getTarget() instanceof BlockRayTraceResult)) - return; - - BlockRayTraceResult result = (BlockRayTraceResult) event.getTarget(); - ClientWorld world = Minecraft.getInstance().world; - BlockPos pos = result.getPos(); - BlockState state = world.getBlockState(pos); - - if (!AllBlocks.REDSTONE_BRIDGE.typeOf(state)) - return; - - Direction facing = state.get(FACING); - Pair positions = itemPositions.get(facing.getIndex()); - RedstoneBridgeTileEntity te = (RedstoneBridgeTileEntity) world.getTileEntity(pos); - - if (te == null) - return; - - Vec3d vec = new Vec3d(pos); - Vec3d first = positions.getLeft().add(vec); - Vec3d second = positions.getRight().add(vec); - - AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(2 / 16f); - AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(2 / 16f); - - TessellatorHelper.prepareForDrawing(); - GlStateManager.enableBlend(); - GlStateManager.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, - GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, - GlStateManager.DestFactor.ZERO); - GlStateManager.disableTexture(); - GlStateManager.depthMask(false); - GlStateManager.matrixMode(5889); - - if (firstBB.contains(result.getHitVec())) { - GlStateManager.lineWidth(2); - WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f); - } else { - GlStateManager.lineWidth(2); - WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f); - } - - if (secondBB.contains(result.getHitVec())) { - GlStateManager.lineWidth(2); - WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f); - } else { - GlStateManager.lineWidth(2); - WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), .5f, .5f, .2f, 1f); - } - - GlStateManager.matrixMode(5888); - GlStateManager.depthMask(true); - GlStateManager.enableTexture(); - GlStateManager.disableBlend(); - GlStateManager.lineWidth(1); - TessellatorHelper.cleanUpAfterDrawing(); + return handleActivated(state, worldIn, pos, player, handIn, hit); } @Override @@ -334,10 +241,15 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool } - public static Pair getFrequencyItemPositions(BlockState state) { + public Pair getFrequencyItemPositions(BlockState state) { Direction facing = state.get(FACING); return itemPositions.get(facing.getIndex()); } + + @Override + public Direction getFrequencyItemFacing(BlockState state) { + return state.get(FACING); + } @Override @OnlyIn(value = Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntity.java index 993ef9408..076c2c074 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/RedstoneBridgeTileEntity.java @@ -3,127 +3,59 @@ package com.simibubi.create.modules.logistics.block; import static net.minecraft.state.properties.BlockStateProperties.POWERED; import com.simibubi.create.AllTileEntities; -import com.simibubi.create.foundation.block.SyncedTileEntity; -import com.simibubi.create.modules.logistics.FrequencyHandler; -import com.simibubi.create.modules.logistics.FrequencyHandler.Frequency; import com.simibubi.create.modules.logistics.IReceiveWireless; import com.simibubi.create.modules.logistics.ITransmitWireless; -import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; -public class RedstoneBridgeTileEntity extends SyncedTileEntity +public class RedstoneBridgeTileEntity extends LinkedTileEntity implements ITickableTileEntity, IReceiveWireless, ITransmitWireless { - public Frequency frequencyFirst; - public Frequency frequencyLast; public boolean receivedSignal; public boolean transmittedSignal; public RedstoneBridgeTileEntity() { super(AllTileEntities.REDSTONE_BRIDGE.type); - frequencyFirst = new Frequency(ItemStack.EMPTY); - frequencyLast = new Frequency(ItemStack.EMPTY); - } - - @Override - public void onLoad() { - super.onLoad(); - if (world.isRemote) - return; - FrequencyHandler.addToNetwork(this); - } - - @Override - public void remove() { - super.remove(); - if (world.isRemote) - return; - FrequencyHandler.removeFromNetwork(this); - } - - public void setFrequency(boolean first, ItemStack stack) { - stack = stack.copy(); - stack.setCount(1); - ItemStack toCompare = first ? frequencyFirst.getStack() : frequencyLast.getStack(); - boolean changed = !ItemStack.areItemsEqual(stack, toCompare) - || !ItemStack.areItemStackTagsEqual(stack, toCompare); - - if (changed) - FrequencyHandler.removeFromNetwork(this); - - if (first) - frequencyFirst = new Frequency(stack); - else - frequencyLast = new Frequency(stack); - - if (!changed) - return; - - sendData(); - FrequencyHandler.addToNetwork(this); - } - - @Override - public Frequency getFrequencyFirst() { - return frequencyFirst; - } - - @Override - public Frequency getFrequencyLast() { - return frequencyLast; } @Override public boolean getSignal() { return transmittedSignal; } - - public void transmit(boolean signal) { - transmittedSignal = signal; - notifySignalChange(); - } - + @Override public void setSignal(boolean powered) { receivedSignal = powered; } - - protected boolean isTransmitter() { - return !getBlockState().get(RedstoneBridgeBlock.RECEIVER); - } - protected boolean isBlockPowered() { - return getBlockState().get(POWERED); + public void transmit(boolean signal) { + transmittedSignal = signal; + notifySignalChange(); } @Override public CompoundNBT write(CompoundNBT compound) { - compound.put("FrequencyFirst", frequencyFirst.getStack().write(new CompoundNBT())); - compound.put("FrequencyLast", frequencyLast.getStack().write(new CompoundNBT())); compound.putBoolean("Transmit", transmittedSignal); return super.write(compound); } @Override public void read(CompoundNBT compound) { - frequencyFirst = new Frequency(ItemStack.read(compound.getCompound("FrequencyFirst"))); - frequencyLast = new Frequency(ItemStack.read(compound.getCompound("FrequencyLast"))); transmittedSignal = compound.getBoolean("Transmit"); super.read(compound); } @Override public void tick() { - if (isTransmitter()) + if (!getBlockState().get(RedstoneBridgeBlock.RECEIVER)) return; if (world.isRemote) return; - if (receivedSignal != isBlockPowered()) { + if (receivedSignal != getBlockState().get(POWERED)) { world.setBlockState(pos, getBlockState().cycle(POWERED)); Direction attachedFace = getBlockState().get(BlockStateProperties.FACING).getOpposite(); BlockPos attachedPos = pos.offset(attachedFace);