From a62dc492d5280e59761b4362727db49206646853 Mon Sep 17 00:00:00 2001 From: simibubi <31564874+simibubi@users.noreply.github.com> Date: Thu, 5 Sep 2019 02:16:44 +0200 Subject: [PATCH] Detect and Filter out - Added the Detector, along with item filtering interfaces - Added filtering to Extractors - Fixed some items jittering on belts - Added text to Frequency and Filter slot highlighting --- .../java/com/simibubi/create/AllBlocks.java | 2 + .../java/com/simibubi/create/AllItems.java | 16 +- .../com/simibubi/create/AllTileEntities.java | 18 +- .../relays/belt/AllBeltAttachments.java | 21 +- .../relays/belt/BeltTileEntity.java | 9 +- .../logistics/block/BeltFunnelBlock.java | 16 +- .../logistics/block/EntityDetectorBlock.java | 241 ++++++++++++++++++ .../block/EntityDetectorTileEntity.java | 41 +++ .../EntityDetectorTileEntityRenderer.java | 30 +++ .../logistics/block/ExtractorBlock.java | 56 +++- .../logistics/block/ExtractorTileEntity.java | 29 ++- .../block/ExtractorTileEntityRenderer.java | 20 ++ .../block/FilteredTileEntityRenderer.java | 74 ++++++ .../logistics/block/IBlockWithFilter.java | 141 ++++++++++ .../logistics/block/IBlockWithFrequency.java | 54 +++- .../modules/logistics/block/IExtractor.java | 21 +- .../modules/logistics/block/IHaveFilter.java | 10 + .../logistics/block/LinkedExtractorBlock.java | 14 +- .../block/LinkedExtractorTileEntity.java | 31 ++- .../LinkedExtractorTileEntityRenderer.java | 23 ++ .../block/LinkedTileEntityRenderer.java | 2 - .../logistics/block/RedstoneBridgeBlock.java | 2 +- .../create/blockstates/entity_detector.json | 23 ++ .../resources/assets/create/lang/en_us.json | 9 + .../create/models/block/entity_detector.json | 92 +++++++ .../models/block/entity_detector_powered.json | 8 + .../block/entity_detector_with_belt.json | 105 ++++++++ .../entity_detector_with_belt_powered.json | 8 + .../create/models/item/entity_detector.json | 83 ++++++ .../assets/create/models/item/extractor.json | 86 ++++++- .../models/item/refined_radiance_cube.json | 6 + .../models/item/refined_rose_quartz.json | 6 + .../create/models/item/rose_quartz.json | 6 + .../create/models/item/rose_quartz_axe.json | 6 + .../models/item/rose_quartz_pickaxe.json | 6 + .../models/item/rose_quartz_shovel.json | 6 + .../create/models/item/rose_quartz_sword.json | 6 + .../textures/block/entity_detector_front.png | Bin 0 -> 443 bytes .../textures/block/entity_detector_off.png | Bin 0 -> 523 bytes .../textures/block/entity_detector_on.png | Bin 0 -> 533 bytes .../textures/item/refined_radiance_cube.png | Bin 0 -> 497 bytes .../textures/item/refined_rose_quartz.png | Bin 0 -> 556 bytes .../create/textures/item/rose_quartz.png | Bin 0 -> 484 bytes .../create/textures/item/rose_quartz_axe.png | Bin 0 -> 479 bytes .../textures/item/rose_quartz_pickaxe.png | Bin 0 -> 527 bytes .../textures/item/rose_quartz_shovel.png | Bin 0 -> 489 bytes .../textures/item/rose_quartz_sword.png | Bin 0 -> 508 bytes .../textures/item/shadow_steel_cube.png | Bin 481 -> 479 bytes 48 files changed, 1272 insertions(+), 55 deletions(-) create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorBlock.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntity.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntityRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntityRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/IHaveFilter.java create mode 100644 src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntityRenderer.java create mode 100644 src/main/resources/assets/create/blockstates/entity_detector.json create mode 100644 src/main/resources/assets/create/models/block/entity_detector.json create mode 100644 src/main/resources/assets/create/models/block/entity_detector_powered.json create mode 100644 src/main/resources/assets/create/models/block/entity_detector_with_belt.json create mode 100644 src/main/resources/assets/create/models/block/entity_detector_with_belt_powered.json create mode 100644 src/main/resources/assets/create/models/item/entity_detector.json create mode 100644 src/main/resources/assets/create/models/item/refined_radiance_cube.json create mode 100644 src/main/resources/assets/create/models/item/refined_rose_quartz.json create mode 100644 src/main/resources/assets/create/models/item/rose_quartz.json create mode 100644 src/main/resources/assets/create/models/item/rose_quartz_axe.json create mode 100644 src/main/resources/assets/create/models/item/rose_quartz_pickaxe.json create mode 100644 src/main/resources/assets/create/models/item/rose_quartz_shovel.json create mode 100644 src/main/resources/assets/create/models/item/rose_quartz_sword.json create mode 100644 src/main/resources/assets/create/textures/block/entity_detector_front.png create mode 100644 src/main/resources/assets/create/textures/block/entity_detector_off.png create mode 100644 src/main/resources/assets/create/textures/block/entity_detector_on.png create mode 100644 src/main/resources/assets/create/textures/item/refined_radiance_cube.png create mode 100644 src/main/resources/assets/create/textures/item/refined_rose_quartz.png create mode 100644 src/main/resources/assets/create/textures/item/rose_quartz.png create mode 100644 src/main/resources/assets/create/textures/item/rose_quartz_axe.png create mode 100644 src/main/resources/assets/create/textures/item/rose_quartz_pickaxe.png create mode 100644 src/main/resources/assets/create/textures/item/rose_quartz_shovel.png create mode 100644 src/main/resources/assets/create/textures/item/rose_quartz_sword.png diff --git a/src/main/java/com/simibubi/create/AllBlocks.java b/src/main/java/com/simibubi/create/AllBlocks.java index b4e8735af..aaa71a97b 100644 --- a/src/main/java/com/simibubi/create/AllBlocks.java +++ b/src/main/java/com/simibubi/create/AllBlocks.java @@ -29,6 +29,7 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; import com.simibubi.create.modules.economy.ShopShelfBlock; import com.simibubi.create.modules.gardens.CocoaLogBlock; import com.simibubi.create.modules.logistics.block.BeltFunnelBlock; +import com.simibubi.create.modules.logistics.block.EntityDetectorBlock; import com.simibubi.create.modules.logistics.block.ExtractorBlock; import com.simibubi.create.modules.logistics.block.FlexcrateBlock; import com.simibubi.create.modules.logistics.block.LinkedExtractorBlock; @@ -107,6 +108,7 @@ public enum AllBlocks { EXTRACTOR(new ExtractorBlock()), LINKED_EXTRACTOR(new LinkedExtractorBlock()), BELT_FUNNEL(new BeltFunnelBlock()), + ENTITY_DETECTOR(new EntityDetectorBlock()), // Symmetry SYMMETRY_PLANE(new PlaneSymmetryBlock()), diff --git a/src/main/java/com/simibubi/create/AllItems.java b/src/main/java/com/simibubi/create/AllItems.java index c97e7dd1c..bccf22f4d 100644 --- a/src/main/java/com/simibubi/create/AllItems.java +++ b/src/main/java/com/simibubi/create/AllItems.java @@ -39,16 +39,18 @@ public enum AllItems { PLACEMENT_HANDGUN( new BuilderGunItem(new Properties().setTEISR(() -> () -> renderUsing(AllItemRenderers.BUILDER_GUN)))), - ANDESITE_ALLOY_CUBE(new Item(standardProperties())), - BLAZE_BRASS_CUBE(new Item(standardProperties())), + ANDESITE_ALLOY_CUBE(new Item(standardProperties())), BLAZE_BRASS_CUBE(new Item(standardProperties())), CHORUS_CHROME_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))), CHROMATIC_COMPOUND_CUBE(new ChromaticCompoundCubeItem(standardProperties().rarity(Rarity.UNCOMMON))), SHADOW_STEEL_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))), - - BLAZING_PICKAXE(new Item(standardProperties())), - BLAZING_SHOVEL(new Item(standardProperties())), - BLAZING_AXE(new Item(standardProperties())), - BLAZING_SWORD(new Item(standardProperties())), + ROSE_QUARTZ(new Item(standardProperties())), REFINED_ROSE_QUARTZ(new Item(standardProperties())), + REFINED_RADIANCE_CUBE(new Item(standardProperties())), + + BLAZING_PICKAXE(new Item(standardProperties())), BLAZING_SHOVEL(new Item(standardProperties())), + BLAZING_AXE(new Item(standardProperties())), BLAZING_SWORD(new Item(standardProperties())), + + ROSE_QUARTZ_PICKAXE(new Item(standardProperties())), ROSE_QUARTZ_SHOVEL(new Item(standardProperties())), + ROSE_QUARTZ_AXE(new Item(standardProperties())), ROSE_QUARTZ_SWORD(new Item(standardProperties())), TREE_FERTILIZER(new TreeFertilizerItem(standardProperties())), diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index c7c93feae..738c00ee1 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -26,9 +26,13 @@ import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntityRenderer; import com.simibubi.create.modules.economy.ShopShelfTileEntity; import com.simibubi.create.modules.logistics.block.BeltFunnelTileEntity; +import com.simibubi.create.modules.logistics.block.EntityDetectorTileEntity; +import com.simibubi.create.modules.logistics.block.EntityDetectorTileEntityRenderer; import com.simibubi.create.modules.logistics.block.ExtractorTileEntity; +import com.simibubi.create.modules.logistics.block.ExtractorTileEntityRenderer; import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity; import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntity; +import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntityRenderer; import com.simibubi.create.modules.logistics.block.LinkedTileEntityRenderer; import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity; import com.simibubi.create.modules.logistics.block.StockswitchTileEntity; @@ -61,10 +65,8 @@ public enum AllTileEntities { MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX), TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE), ENCASED_SHAFT(EncasedShaftTileEntity::new, AllBlocks.ENCASED_SHAFT, AllBlocks.ENCASED_BELT), - ENCASED_FAN(EncasedFanTileEntity::new, AllBlocks.ENCASED_FAN), - CLUTCH(ClutchTileEntity::new, AllBlocks.CLUTCH), - GEARSHIFT(GearshiftTileEntity::new, AllBlocks.GEARSHIFT), - BELT(BeltTileEntity::new, AllBlocks.BELT), + ENCASED_FAN(EncasedFanTileEntity::new, AllBlocks.ENCASED_FAN), CLUTCH(ClutchTileEntity::new, AllBlocks.CLUTCH), + GEARSHIFT(GearshiftTileEntity::new, AllBlocks.GEARSHIFT), BELT(BeltTileEntity::new, AllBlocks.BELT), MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON), DRILL(DrillTileEntity::new, AllBlocks.DRILL), CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL), @@ -74,10 +76,10 @@ public enum AllTileEntities { // Logistics REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE), STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH), - FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), - EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR), + FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR), LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR), BELT_FUNNEL(BeltFunnelTileEntity::new, AllBlocks.BELT_FUNNEL), + ENTITY_DETECTOR(EntityDetectorTileEntity::new, AllBlocks.ENTITY_DETECTOR), // Economy SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF), @@ -125,7 +127,9 @@ public enum AllTileEntities { bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer()); bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer()); bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer()); - bind(LinkedExtractorTileEntity.class, new LinkedTileEntityRenderer()); + bind(LinkedExtractorTileEntity.class, new LinkedExtractorTileEntityRenderer()); + bind(ExtractorTileEntity.class, new ExtractorTileEntityRenderer()); + bind(EntityDetectorTileEntity.class, new EntityDetectorTileEntityRenderer()); } @OnlyIn(Dist.CLIENT) diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java index 969705aca..3ff066bfe 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/AllBeltAttachments.java @@ -15,10 +15,12 @@ import net.minecraft.nbt.ListNBT; import net.minecraft.nbt.NBTUtil; import net.minecraft.util.math.BlockPos; import net.minecraft.world.IWorld; +import net.minecraft.world.World; public enum AllBeltAttachments { BELT_FUNNEL(AllBlocks.BELT_FUNNEL), + BELT_OBSERVER(AllBlocks.ENTITY_DETECTOR), ; @@ -29,7 +31,7 @@ public enum AllBeltAttachments { } public interface IBeltAttachment { - public Optional getValidAttachmentFor(BeltTileEntity te); + public List getPotentialAttachmentLocations(BeltTileEntity te); public Optional getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state); @@ -80,10 +82,19 @@ public enum AllBeltAttachments { public void findAttachments(BeltTileEntity belt) { for (AllBeltAttachments ba : AllBeltAttachments.values()) { - Optional validAttachmentFor = ba.attachment.getValidAttachmentFor(belt); - if (validAttachmentFor.isPresent()) { - BlockPos pos = validAttachmentFor.get(); - addAttachment(belt.getWorld(), pos); + List attachmentPositions = ba.attachment.getPotentialAttachmentLocations(belt); + World world = belt.getWorld(); + for (BlockPos potentialPos : attachmentPositions) { + if (!world.isBlockPresent(potentialPos)) + continue; + BlockState state = world.getBlockState(potentialPos); + if (!(state.getBlock() instanceof IBeltAttachment)) + continue; + Optional validBeltPos = ((IBeltAttachment) state.getBlock()).getValidBeltPositionFor(world, potentialPos, state); + if (!validBeltPos.isPresent()) + continue; + if (validBeltPos.get().equals(belt.getPos())) + addAttachment(world, potentialPos); } } } diff --git a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java index 48cb63294..1eea21399 100644 --- a/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/contraptions/relays/belt/BeltTileEntity.java @@ -134,13 +134,13 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn passengers.forEach((entity, info) -> { if (!canTransport(entity)) toRemove.add(entity); - if (info.ticksSinceLastCollision > 0) { + if (info.ticksSinceLastCollision > 1) { toRemove.add(entity); } info.tick(); }); toRemove.forEach(e -> { - if (e instanceof ItemEntity) + if (e instanceof ItemEntity && ((ItemEntity) e).getAge() < 0) ((ItemEntity) e).setAgeToCreativeDespawnTime(); passengers.remove(e); }); @@ -188,8 +188,10 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn BeltTileEntity belt = (BeltTileEntity) te; for (BeltAttachmentState state : belt.attachmentTracker.attachments) { - if (state.attachment.handleEntity(belt, entityIn, state)) + if (state.attachment.handleEntity(belt, entityIn, state)) { + info.ticksSinceLastCollision--; return; + } } final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); @@ -242,6 +244,7 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn .grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z))) .isEmpty()) { entityIn.setMotion(0, 0, 0); + info.ticksSinceLastCollision--; return; } } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/BeltFunnelBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/BeltFunnelBlock.java index 320660dfc..004383143 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/BeltFunnelBlock.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/BeltFunnelBlock.java @@ -1,5 +1,7 @@ package com.simibubi.create.modules.logistics.block; +import java.util.Arrays; +import java.util.List; import java.util.Optional; import com.simibubi.create.AllBlocks; @@ -7,6 +9,8 @@ import com.simibubi.create.foundation.block.IWithTileEntity; import com.simibubi.create.foundation.utility.VecHelper; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; import net.minecraft.block.Block; @@ -113,13 +117,8 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, } @Override - public Optional getValidAttachmentFor(BeltTileEntity te) { - BlockPos validPos = te.getPos().up(); - BlockState blockState = te.getWorld().getBlockState(validPos); - if (blockState.getBlock() != this - || blockState.get(HORIZONTAL_FACING).getAxis() != te.getBlockState().get(HORIZONTAL_FACING).getAxis()) - return Optional.empty(); - return Optional.of(validPos); + public List getPotentialAttachmentLocations(BeltTileEntity te) { + return Arrays.asList(te.getPos().up()); } @Override @@ -136,7 +135,8 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment, public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) { if (!(entity instanceof ItemEntity)) return false; - if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > .4f) + boolean slope = te.getBlockState().get(BeltBlock.SLOPE) != Slope.HORIZONTAL; + if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > (slope ? .6f : .4f)) return false; entity.setMotion(Vec3d.ZERO); diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorBlock.java b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorBlock.java new file mode 100644 index 000000000..5aad21ed4 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorBlock.java @@ -0,0 +1,241 @@ +package com.simibubi.create.modules.logistics.block; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.Random; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.foundation.block.IWithTileEntity; +import com.simibubi.create.foundation.utility.VecHelper; +import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; +import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.IBeltAttachment; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Part; +import com.simibubi.create.modules.contraptions.relays.belt.BeltBlock.Slope; +import com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.HorizontalBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.BlockItemUseContext; +import net.minecraft.item.ItemStack; +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.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.IWorld; +import net.minecraft.world.World; + +public class EntityDetectorBlock extends HorizontalBlock + implements IWithTileEntity, IBeltAttachment, IBlockWithFilter { + + public static BooleanProperty POWERED = BlockStateProperties.POWERED; + public static BooleanProperty BELT = BooleanProperty.create("belt"); + + private static final List itemPositions = new ArrayList<>(Direction.values().length); + + public EntityDetectorBlock() { + super(Properties.from(Blocks.ANDESITE)); + setDefaultState(getDefaultState().with(POWERED, false).with(BELT, false)); + cacheItemPositions(); + } + + @Override + public TileEntity createTileEntity(BlockState state, IBlockReader world) { + return new EntityDetectorTileEntity(); + } + + @Override + public boolean hasTileEntity(BlockState state) { + return true; + } + + @Override + public BlockState updatePostPlacement(BlockState stateIn, Direction facing, BlockState facingState, IWorld worldIn, + BlockPos currentPos, BlockPos facingPos) { + if (facing == stateIn.get(HORIZONTAL_FACING)) + stateIn = stateIn.with(BELT, shouldHaveExtension(stateIn, worldIn, currentPos)); + return stateIn; + } + + @Override + protected void fillStateContainer(Builder builder) { + builder.add(POWERED, HORIZONTAL_FACING, BELT); + super.fillStateContainer(builder); + } + + private boolean shouldHaveExtension(BlockState state, IWorld world, BlockPos pos) { + Direction direction = state.get(HORIZONTAL_FACING); + BlockState blockState = world.getBlockState(pos.offset(direction)); + + if (!AllBlocks.BELT.typeOf(blockState)) + return false; + if (blockState.get(BeltBlock.SLOPE) != Slope.HORIZONTAL) + return false; + if (blockState.get(BeltBlock.PART) != Part.MIDDLE) + return false; + if (blockState.get(BeltBlock.HORIZONTAL_FACING).getAxis() == direction.getAxis()) + return false; + + return true; + } + + @Override + public BlockState getStateForPlacement(BlockItemUseContext context) { + BlockState state = getDefaultState(); + + if (context.getFace().getAxis().isHorizontal()) { + state = state.with(HORIZONTAL_FACING, context.getFace().getOpposite()); + } else { + state = state.with(HORIZONTAL_FACING, context.getPlacementHorizontalFacing()); + } + + state = state.with(BELT, shouldHaveExtension(state, context.getWorld(), context.getPos())); + + return state; + } + + @Override + public List getPotentialAttachmentLocations(BeltTileEntity te) { + Direction side = te.getBlockState().get(BeltBlock.HORIZONTAL_FACING).rotateY(); + return Arrays.asList(te.getPos().offset(side), te.getPos().offset(side.getOpposite())); + } + + @Override + public Optional getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state) { + if (!state.get(BELT)) + return Optional.empty(); + return Optional.of(pos.offset(state.get(HORIZONTAL_FACING))); + } + + @Override + public boolean canProvidePower(BlockState state) { + return state.get(POWERED); + } + + @Override + public int getWeakPower(BlockState blockState, IBlockReader blockAccess, BlockPos pos, Direction side) { + return canProvidePower(blockState) ? 15 : 0; + } + + @Override + public boolean canConnectRedstone(BlockState state, IBlockReader world, BlockPos pos, Direction side) { + return side != state.get(HORIZONTAL_FACING).getOpposite(); + } + + @Override + public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, + BlockRayTraceResult hit) { + return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit); + } + + @Override + public void onReplaced(BlockState state, World worldIn, BlockPos pos, BlockState newState, boolean isMoving) { + if (newState.getBlock() != this || newState.with(POWERED, false) != state.with(POWERED, false)) + onAttachmentRemoved(worldIn, pos, state); + if (state.hasTileEntity() && state.getBlock() != newState.getBlock()) { + worldIn.removeTileEntity(pos); + } + } + + @Override + public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { + if (oldState.getBlock() != this || oldState.with(POWERED, false) != state.with(POWERED, false)) + onAttachmentPlaced(worldIn, pos, state); + } + + @Override + public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) { + + if (state.processingEntity != entity) { + state.processingEntity = entity; + state.processingDuration = 0; + withTileEntityDo(te.getWorld(), state.attachmentPos, detectorTE -> { + ItemStack filter = detectorTE.getFilter(); + if (filter.isEmpty()) + return; + if (!(entity instanceof ItemEntity) + || !ItemStack.areItemsEqual(((ItemEntity) entity).getItem(), filter)) { + state.processingDuration = -1; + return; + } + }); + } + + if (entity.getPositionVec().distanceTo(VecHelper.getCenterOf(te.getPos())) > .5f) + return false; + if (state.processingDuration == -1) { + return false; + } + + World world = te.getWorld(); + BlockState blockState = world.getBlockState(state.attachmentPos); + if (blockState.get(POWERED)) + return false; + + state.processingDuration = -1; + world.setBlockState(state.attachmentPos, blockState.with(POWERED, true)); + world.getPendingBlockTicks().scheduleTick(state.attachmentPos, this, 4); + world.notifyNeighborsOfStateChange(state.attachmentPos, this); + + return false; + } + + @Override + public void tick(BlockState state, World worldIn, BlockPos pos, Random random) { + worldIn.setBlockState(pos, state.with(POWERED, false)); + worldIn.notifyNeighborsOfStateChange(pos, this); + } + + private void cacheItemPositions() { + if (!itemPositions.isEmpty()) + return; + + Vec3d position = Vec3d.ZERO; + Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO); + float zFightOffset = 1 / 128f; + + for (int i = 0; i < 4; i++) { + Direction facing = Direction.byHorizontalIndex(i); + position = new Vec3d(8f / 16f + zFightOffset, 15f / 16f, 17.75f / 16f); + + float angle = facing.getHorizontalAngle(); + if (facing.getAxis() == Axis.X) + angle = -angle; + + position = VecHelper.rotate(position.subtract(shift), angle, Axis.Y).add(shift); + + itemPositions.add(position); + } + } + + @Override + public float getItemHitboxScale() { + return 1.76f / 16f; + } + + @Override + public Vec3d getFilterPosition(BlockState state) { + Direction facing = state.get(HORIZONTAL_FACING); + return itemPositions.get(facing.getHorizontalIndex()); + } + + @Override + public Direction getFilterFacing(BlockState state) { + return state.get(HORIZONTAL_FACING); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntity.java b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntity.java new file mode 100644 index 000000000..d09902dc2 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntity.java @@ -0,0 +1,41 @@ +package com.simibubi.create.modules.logistics.block; + +import com.simibubi.create.AllTileEntities; +import com.simibubi.create.foundation.block.SyncedTileEntity; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; + +public class EntityDetectorTileEntity extends SyncedTileEntity implements IHaveFilter { + + private ItemStack filter; + + public EntityDetectorTileEntity() { + super(AllTileEntities.ENTITY_DETECTOR.type); + filter = ItemStack.EMPTY; + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.put("Filter", filter.serializeNBT()); + return super.write(compound); + } + + @Override + public void read(CompoundNBT compound) { + filter = ItemStack.read(compound.getCompound("Filter")); + super.read(compound); + } + + @Override + public void setFilter(ItemStack stack) { + filter = stack; + sendData(); + } + + @Override + public ItemStack getFilter() { + return filter; + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntityRenderer.java new file mode 100644 index 000000000..c824f1f10 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/EntityDetectorTileEntityRenderer.java @@ -0,0 +1,30 @@ +package com.simibubi.create.modules.logistics.block; + +import com.mojang.blaze3d.platform.GLX; + +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; +import net.minecraft.state.properties.BlockStateProperties; + +public class EntityDetectorTileEntityRenderer extends TileEntityRenderer { + + private FilteredTileEntityRenderer filterRenderer; + + public EntityDetectorTileEntityRenderer() { + filterRenderer = new FilteredTileEntityRenderer(); + } + + @Override + public void render(EntityDetectorTileEntity tileEntityIn, double x, double y, double z, float partialTicks, + int destroyStage) { + super.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + + int i = tileEntityIn.getWorld().getCombinedLight(tileEntityIn.getPos().up() + .offset(tileEntityIn.getBlockState().get(BlockStateProperties.HORIZONTAL_FACING)), 0); + int j = i % 65536; + int k = i / 65536; + GLX.glMultiTexCoord2f(GLX.GL_TEXTURE1, (float) j, (float) k); + + filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + } + +} 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 7d5291ce2..47e5aa606 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 @@ -1,5 +1,10 @@ package com.simibubi.create.modules.logistics.block; +import java.util.ArrayList; +import java.util.List; + +import com.simibubi.create.foundation.utility.VecHelper; + import net.minecraft.block.Block; import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; @@ -12,8 +17,10 @@ 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.Direction.Axis; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.shapes.ISelectionContext; import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShapes; @@ -21,16 +28,18 @@ import net.minecraft.world.IBlockReader; import net.minecraft.world.IWorldReader; import net.minecraft.world.World; -public class ExtractorBlock extends HorizontalBlock { +public class ExtractorBlock extends HorizontalBlock implements IBlockWithFilter { public static BooleanProperty POWERED = BlockStateProperties.POWERED; public static final VoxelShape SHAPE_NORTH = makeCuboidShape(4, 2, -1, 12, 10, 5), SHAPE_SOUTH = makeCuboidShape(4, 2, 11, 12, 10, 17), SHAPE_WEST = makeCuboidShape(-1, 2, 4, 5, 10, 12), SHAPE_EAST = makeCuboidShape(11, 2, 4, 17, 10, 12); - + private static final List itemPositions = new ArrayList<>(Direction.values().length); + public ExtractorBlock() { super(Properties.from(Blocks.ANDESITE)); setDefaultState(getDefaultState().with(POWERED, false)); + cacheItemPositions(); } @Override @@ -52,7 +61,7 @@ public class ExtractorBlock extends HorizontalBlock { @Override public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { - return false; + return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit); } @Override @@ -71,6 +80,8 @@ public class ExtractorBlock extends HorizontalBlock { @Override public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { updateObservedInventory(state, worldIn, pos); + + cacheItemPositions(); } @Override @@ -125,4 +136,43 @@ public class ExtractorBlock extends HorizontalBlock { return VoxelShapes.empty(); } + private void cacheItemPositions() { +// if (!itemPositions.isEmpty()) +// return; + itemPositions.clear(); + + Vec3d position = Vec3d.ZERO; + Vec3d shift = VecHelper.getCenterOf(BlockPos.ZERO); + float zFightOffset = 1 / 128f; + + for (int i = 0; i < 4; i++) { + Direction facing = Direction.byHorizontalIndex(i); + position = new Vec3d(8f / 16f + zFightOffset, 10.5f / 16f, 2.25f / 16f); + + float angle = facing.getHorizontalAngle(); + if (facing.getAxis() == Axis.X) + angle = -angle; + + position = VecHelper.rotate(position.subtract(shift), angle, Axis.Y).add(shift); + + itemPositions.add(position); + } + } + + @Override + public float getItemHitboxScale() { + return 1.76f / 16f; + } + + @Override + public Vec3d getFilterPosition(BlockState state) { + Direction facing = state.get(HORIZONTAL_FACING).getOpposite(); + return itemPositions.get(facing.getHorizontalIndex()); + } + + @Override + public Direction getFilterFacing(BlockState state) { + return state.get(HORIZONTAL_FACING).getOpposite(); + } + } 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 index 87fb62cb8..135ed11bc 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntity.java @@ -3,15 +3,18 @@ package com.simibubi.create.modules.logistics.block; import com.simibubi.create.AllTileEntities; import com.simibubi.create.foundation.block.SyncedTileEntity; +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.math.BlockPos; import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; -public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, ITickableTileEntity { +public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, ITickableTileEntity, IHaveFilter { private State state; + private ItemStack filter; private int cooldown; private LazyOptional inventory; private boolean initialize; @@ -20,6 +23,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, super(AllTileEntities.EXTRACTOR.type); state = State.WAITING_FOR_INVENTORY; inventory = LazyOptional.empty(); + filter = ItemStack.EMPTY; } @Override @@ -27,6 +31,18 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, return state; } + @Override + public void read(CompoundNBT compound) { + filter = ItemStack.read(compound.getCompound("Filter")); + super.read(compound); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.put("Filter", filter.serializeNBT()); + return super.write(compound); + } + @Override public void onLoad() { initialize = true; @@ -68,4 +84,15 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor, this.inventory = inventory; } + @Override + public void setFilter(ItemStack stack) { + filter = stack; + sendData(); + } + + @Override + public ItemStack getFilter() { + return filter; + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntityRenderer.java new file mode 100644 index 000000000..3146efe77 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/ExtractorTileEntityRenderer.java @@ -0,0 +1,20 @@ +package com.simibubi.create.modules.logistics.block; + +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; + +public class ExtractorTileEntityRenderer extends TileEntityRenderer { + + FilteredTileEntityRenderer filterRenderer; + + public ExtractorTileEntityRenderer() { + filterRenderer = new FilteredTileEntityRenderer(); + } + + @Override + public void render(ExtractorTileEntity tileEntityIn, double x, double y, double z, float partialTicks, + int destroyStage) { + super.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java new file mode 100644 index 000000000..15c31f7b7 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/FilteredTileEntityRenderer.java @@ -0,0 +1,74 @@ +package com.simibubi.create.modules.logistics.block; + +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.item.ItemStack; +import net.minecraft.tileentity.TileEntity; +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 FilteredTileEntityRenderer { + + public void render(T tileEntityIn, double x, double y, double z, + float partialTicks, int destroyStage) { + BlockState state = tileEntityIn.getBlockState(); + IBlockWithFilter block = (IBlockWithFilter) state.getBlock(); + Direction facing = block.getFilterFacing(state); + float scale = block.getItemHitboxScale(); + + TessellatorHelper.prepareForDrawing(); + + Vec3d position = block.getFilterPosition(state); + BlockPos pos = tileEntityIn.getPos(); + GlStateManager.translated(pos.getX(), pos.getY(), pos.getZ()); + + renderFilterItem(tileEntityIn.getFilter(), position, facing, scale - 2 / 16f); + + TessellatorHelper.cleanUpAfterDrawing(); + + } + + private void renderFilterItem(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 = 0; + float offZ = !blockItem ? 1 / 4f + 2 * scaleDiff - 1/16f : 1/16f; + if (vertical) + offZ = -offZ; + + float rotX = vertical ? 90 : 0 - (blockItem ? -67.5f : 67.5f); + float rotY = vertical ? 0 : facing.getHorizontalAngle() + (blockItem ? 180 : 0); + float rotZ = vertical && facing == Direction.DOWN ? 180 : 0; + if (facing.getAxis() == Axis.X) { + rotY = -rotY; + } + + float scale = !blockItem ? .25f : .5f; + scale *= 1 + 8 * scaleDiff; + + GlStateManager.pushMatrix(); + GlStateManager.translated(position.x, position.y, position.z); + 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/IBlockWithFilter.java b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java new file mode 100644 index 000000000..02f95149a --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFilter.java @@ -0,0 +1,141 @@ +package com.simibubi.create.modules.logistics.block; + +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.BufferBuilder; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +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.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; +import net.minecraft.util.math.Vec3i; +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 IBlockWithFilter { + + public Vec3d getFilterPosition(BlockState state); + + public Direction getFilterFacing(BlockState state); + + public default float getItemHitboxScale() { + return 2 / 16f; + } + + public default boolean handleActivatedFilterSlots(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, + Hand handIn, BlockRayTraceResult hit) { + TileEntity te = worldIn.getTileEntity(pos); + if (te == null || !(te instanceof IHaveFilter)) + return false; + + IHaveFilter actor = (IHaveFilter) te; + Vec3d vec = new Vec3d(pos); + Vec3d position = vec.add(getFilterPosition(state)); + ItemStack stack = player.getHeldItem(handIn); + float scale = getItemHitboxScale(); + + if (new AxisAlignedBB(position, position).grow(scale * 2).contains(hit.getHitVec())) { + if (worldIn.isRemote) + return true; + actor.setFilter(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 IBlockWithFilter)) + return; + + IBlockWithFilter filterBlock = (IBlockWithFilter) state.getBlock(); + Vec3d vec = new Vec3d(pos); + Vec3d position = filterBlock.getFilterPosition(state).add(vec); + float scale = filterBlock.getItemHitboxScale(); + + AxisAlignedBB bb = new AxisAlignedBB(position, position).grow(scale, scale / 1.25f, scale).offset(0, -scale / 16f, 0); + boolean contains = bb.grow(scale).contains(result.getHitVec()); + + 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); + + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder bufferbuilder = tessellator.getBuffer(); + bufferbuilder.begin(3, DefaultVertexFormats.POSITION_COLOR); + bb = bb.grow(1 / 128f); + Vec3d center = bb.getCenter().subtract(vec); + bb = bb.offset(center); + Direction facing = filterBlock.getFilterFacing(state); + Vec3i direction = facing.getDirectionVec(); + GlStateManager.pushMatrix(); + GlStateManager.translated(position.x, position.y, position.z); + GlStateManager.rotated(22.5f, direction.getZ(), 0, -direction.getX()); + GlStateManager.translated(-center.x, -center.y, -center.z); + GlStateManager.translated(-position.x, -position.y, -position.z); + + if (contains) { + GlStateManager.lineWidth(2); + WorldRenderer.drawBoundingBox(bufferbuilder, bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ, .5f, 1, .75f, 1f); + } else { + GlStateManager.lineWidth(2); + WorldRenderer.drawBoundingBox(bufferbuilder, bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ, .25f, .5f, .35f, 1f); + } + + tessellator.draw(); + + GlStateManager.popMatrix(); + GlStateManager.enableTexture(); + GlStateManager.depthMask(true); + + if (contains) { + float textScale = 1/128f; + GlStateManager.translated(position.x, position.y, position.z); + GlStateManager.rotated(facing.getHorizontalAngle() * (facing.getAxis() == Axis.X ? -1 : 1), 0, 1, 0); + GlStateManager.scaled(textScale, -textScale, textScale); + GlStateManager.translated(17.5f, -5f, -5f); + GlStateManager.rotated(67.5f, 1, 0, 0); + + String text = "Filter"; + Minecraft.getInstance().fontRenderer.drawString(text, 0, 0, 0x88FFBB); + GlStateManager.translated(0, 0, -1/4f); + Minecraft.getInstance().fontRenderer.drawString(text, 1, 1, 0x224433); + } + GlStateManager.disableBlend(); + + GlStateManager.lineWidth(1); + TessellatorHelper.cleanUpAfterDrawing(); + } + +} 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 index d5bc08d25..bdbd6e901 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IBlockWithFrequency.java @@ -15,6 +15,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.Hand; +import net.minecraft.util.Direction.Axis; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockRayTraceResult; @@ -30,13 +31,14 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber; 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, + public default boolean handleActivatedFrequencySlots(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) { TileEntity te = worldIn.getTileEntity(pos); if (te == null || !(te instanceof IHaveWireless)) @@ -87,6 +89,7 @@ public interface IBlockWithFrequency { Vec3d first = positions.getLeft().add(vec); Vec3d second = positions.getRight().add(vec); float scale = freqBlock.getItemHitboxScale(); + Direction facing = freqBlock.getFrequencyItemFacing(state); AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(scale); AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(scale); @@ -100,7 +103,8 @@ public interface IBlockWithFrequency { GlStateManager.depthMask(false); GlStateManager.matrixMode(5889); - if (firstBB.contains(result.getHitVec())) { + boolean firstContains = firstBB.contains(result.getHitVec()); + if (firstContains) { GlStateManager.lineWidth(2); WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f); } else { @@ -108,7 +112,8 @@ public interface IBlockWithFrequency { WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f); } - if (secondBB.contains(result.getHitVec())) { + boolean secondContains = secondBB.contains(result.getHitVec()); + if (secondContains) { GlStateManager.lineWidth(2); WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f); } else { @@ -119,6 +124,49 @@ public interface IBlockWithFrequency { GlStateManager.matrixMode(5888); GlStateManager.depthMask(true); GlStateManager.enableTexture(); + + if (firstContains) { + GlStateManager.pushMatrix(); + float textScale = 1 / 128f; + GlStateManager.translated(first.x, first.y, first.z); + if (facing.getAxis().isVertical()) { + GlStateManager.rotated(180, 0, 1, 0); + GlStateManager.rotated(facing == Direction.UP ? -90 : 90, 1, 0, 0); + } else { + GlStateManager.rotated(facing.getHorizontalAngle() * (facing.getAxis() == Axis.X ? -1 : 1), 0, 1, 0); + } + GlStateManager.scaled(textScale, -textScale, textScale); + GlStateManager.translated(19.5f, -5f, 10f); + + String text = "Freq. #2"; + Minecraft.getInstance().fontRenderer.drawString(text, 0, 0, 0xFFFF99); + GlStateManager.translated(0, 0, -1 / 4f); + Minecraft.getInstance().fontRenderer.drawString(text, 1, 1, 0x444433); + GlStateManager.popMatrix(); + } + + if (secondContains) { + GlStateManager.pushMatrix(); + float textScale = 1 / 128f; + GlStateManager.translated(second.x, second.y, second.z); + if (facing.getAxis().isVertical()) { + GlStateManager.rotated(180, 0, 1, 0); + GlStateManager.rotated(facing == Direction.UP ? -90 : 90, 1, 0, 0); + } else { + GlStateManager.rotated(facing.getHorizontalAngle() * (facing.getAxis() == Axis.X ? -1 : 1), 0, 1, 0); + } + GlStateManager.scaled(textScale, -textScale, textScale); + GlStateManager.translated(19.5f, -5f, 10f); + + String text = "Freq. #1"; + Minecraft.getInstance().fontRenderer.drawString(text, 0, 0, 0xFFFF99); + GlStateManager.translated(0, 0, -1 / 4f); + Minecraft.getInstance().fontRenderer.drawString(text, 1, 1, 0x444433); + GlStateManager.popMatrix(); + } + + GlStateManager.disableBlend(); + 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 index 508031616..0e073d6fb 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IExtractor.java @@ -44,9 +44,15 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { boolean hasInventory = getInventory().isPresent(); ItemStack toExtract = ItemStack.EMPTY; - if (hasSpace && hasInventory) + if (hasSpace && hasInventory) { toExtract = extract(true); + ItemStack filter = (this instanceof IHaveFilter) ? filter = ((IHaveFilter) this).getFilter() + : ItemStack.EMPTY; + if (!filter.isEmpty() && !ItemStack.areItemsEqual(toExtract, filter)) + toExtract = ItemStack.EMPTY; + } + if (state == State.WAITING_FOR_ENTITY) { if (hasSpace) setState(State.RUNNING); @@ -79,8 +85,13 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { boolean hasInventory = getInventory().isPresent(); ItemStack toExtract = ItemStack.EMPTY; - if (hasSpace && hasInventory) + if (hasSpace && hasInventory) { toExtract = extract(true); + ItemStack filter = (this instanceof IHaveFilter) ? filter = ((IHaveFilter) this).getFilter() + : ItemStack.EMPTY; + if (!filter.isEmpty() && !ItemStack.areItemsEqual(toExtract, filter)) + toExtract = ItemStack.EMPTY; + } if (getState() == State.WAITING_FOR_INVENTORY) { if (!hasInventory) { @@ -101,9 +112,11 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { default ItemStack extract(boolean simulate) { IItemHandler inv = getInventory().orElse(null); ItemStack extracting = ItemStack.EMPTY; + ItemStack filter = (this instanceof IHaveFilter) ? filter = ((IHaveFilter) this).getFilter() : ItemStack.EMPTY; + int extractionCount = filter.isEmpty() ? EXTRACTION_COUNT : filter.getCount(); for (int slot = 0; slot < inv.getSlots(); slot++) { - ItemStack stack = inv.extractItem(slot, EXTRACTION_COUNT - extracting.getCount(), true); + ItemStack stack = inv.extractItem(slot, extractionCount - extracting.getCount(), true); ItemStack compare = stack.copy(); compare.setCount(extracting.getCount()); if (!extracting.isEmpty() && !extracting.equals(compare, false)) @@ -116,7 +129,7 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator { if (!simulate) inv.extractItem(slot, stack.getCount(), false); - if (extracting.getCount() >= EXTRACTION_COUNT) + if (extracting.getCount() >= extractionCount) break; } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/IHaveFilter.java b/src/main/java/com/simibubi/create/modules/logistics/block/IHaveFilter.java new file mode 100644 index 000000000..7784babd3 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/IHaveFilter.java @@ -0,0 +1,10 @@ +package com.simibubi.create.modules.logistics.block; + +import net.minecraft.item.ItemStack; + +public interface IHaveFilter { + + public void setFilter(ItemStack stack); + public ItemStack getFilter(); + +} 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 a3f50baef..40ba35221 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 @@ -35,12 +35,12 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr 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(); @@ -60,7 +60,7 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr 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); + || handleActivatedFrequencySlots(state, worldIn, pos, player, handIn, hit); } private void cacheItemPositions() { @@ -74,7 +74,7 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr for (int i = 0; i < 4; i++) { Direction facing = Direction.byHorizontalIndex(i); - first = new Vec3d(11.5f / 16f + zFightOffset, 4f / 16f, 14f / 16f ); + 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(); @@ -88,10 +88,10 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr } } - + @Override public float getItemHitboxScale() { - return 3/32f; + return 3 / 32f; } @Override @@ -104,5 +104,5 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr 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 index 7945b0029..a4d1ec03f 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntity.java @@ -5,6 +5,8 @@ import static net.minecraft.state.properties.BlockStateProperties.POWERED; import com.simibubi.create.AllTileEntities; import com.simibubi.create.modules.logistics.IReceiveWireless; +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.math.BlockPos; @@ -12,11 +14,12 @@ import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.items.IItemHandler; public class LinkedExtractorTileEntity extends LinkedTileEntity - implements IReceiveWireless, ITickableTileEntity, IExtractor { + implements IReceiveWireless, ITickableTileEntity, IExtractor, IHaveFilter { public boolean receivedSignal; private State state; + private ItemStack filter; private int cooldown; private LazyOptional inventory; @@ -24,13 +27,26 @@ public class LinkedExtractorTileEntity extends LinkedTileEntity super(AllTileEntities.LINKED_EXTRACTOR.type); state = State.WAITING_FOR_INVENTORY; inventory = LazyOptional.empty(); + filter = ItemStack.EMPTY; } @Override public void setSignal(boolean powered) { receivedSignal = powered; } - + + @Override + public void read(CompoundNBT compound) { + filter = ItemStack.read(compound.getCompound("Filter")); + super.read(compound); + } + + @Override + public CompoundNBT write(CompoundNBT compound) { + compound.put("Filter", filter.serializeNBT()); + return super.write(compound); + } + @Override public void tick() { IExtractor.super.tick(); @@ -75,4 +91,15 @@ public class LinkedExtractorTileEntity extends LinkedTileEntity this.inventory = inventory; } + @Override + public void setFilter(ItemStack stack) { + filter = stack; + sendData(); + } + + @Override + public ItemStack getFilter() { + return filter; + } + } diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntityRenderer.java new file mode 100644 index 000000000..e066e8579 --- /dev/null +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedExtractorTileEntityRenderer.java @@ -0,0 +1,23 @@ +package com.simibubi.create.modules.logistics.block; + +import net.minecraft.client.renderer.tileentity.TileEntityRenderer; + +public class LinkedExtractorTileEntityRenderer extends TileEntityRenderer { + + LinkedTileEntityRenderer linkRenderer; + FilteredTileEntityRenderer filterRenderer; + + public LinkedExtractorTileEntityRenderer() { + linkRenderer = new LinkedTileEntityRenderer(); + filterRenderer = new FilteredTileEntityRenderer(); + } + + @Override + public void render(LinkedExtractorTileEntity tileEntityIn, double x, double y, double z, float partialTicks, + int destroyStage) { + super.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + linkRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + filterRenderer.render(tileEntityIn, x, y, z, partialTicks, destroyStage); + } + +} diff --git a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java index d18190fa4..ca5dc0ca9 100644 --- a/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java +++ b/src/main/java/com/simibubi/create/modules/logistics/block/LinkedTileEntityRenderer.java @@ -23,8 +23,6 @@ public class LinkedTileEntityRenderer extends TileEntityRendererPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0Z>UqK~y+Ty^_05 z!!Q(v<2Z5CB#lxQZUb}!iG@rZy0Ee!fyB-u@B$3%yi0ipX1bt=cR*FsOD@jE;dhNf zq*lPhujtozPL7Xl`H;KYfwoPHRieOiZE)iTQo~@lN;ot1x)xO_QXcy~kC%c`qG|QV zbjp}*=#^>Em)D70fV#K$$-3RQHg^~t9wQ`S82Y{silXQ*K%U2AtJ_78rRi3%EGwGL znhbe*xW?)8Li~CM$8qP&lw1XS2Gh%2z|jMcS2e)yQuwCm$-bNAg6afLWTggHVU*+v zFY%F@C@bs2xfNUiIX!S?+qF7|ZZnxp@(OooCsn3z zo8yytWj|HC`nT<(ID@cs(gbJ2uqM&yD~aIOvt{d@-u l-`99IJ>X3UwRe!xv`Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ia1lK~y+TZIaDS z8$k@m=VNz5zJP#0gz$u|7Wa!+w54sf%q_H{0XsVbgZbYNgVAv2bow zm{=BewW;*?n@>I_&I)Jb%Bqe>55J$48h$$;4Xq@R)_3!DW4~NXtkLv@w%51HpFJ+# zl{!_beyLW|LMN@0>S9{f-dJrYrJD)p)`!=p*QL@^rRZr?A|xp_v!QE4(zn;M%17dn z>!;&`9%oSW2=Q@p2B+r$`uS>ic62~iWIqJDOkfm4?A7@gh{MwEd_2P`)^Ynu>HCj+UYhym*+P!?jRzg|u#62#ER97H6Kwc~4>>8n zl#~7PRh#AewvqUFcH+uH{Cc~>%F%Q@!1l{0>n+R7_F{90NG69$sSn=TBq*-;I2v@9 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/block/entity_detector_on.png b/src/main/resources/assets/create/textures/block/entity_detector_on.png new file mode 100644 index 0000000000000000000000000000000000000000..973bd2de77ace0ea7b721df15e9023b14f71fe12 GIT binary patch literal 533 zcmV+w0_y#VP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0jfzvK~y+TZBjc< z13?U(&+de5HeVD3DL^0!5LA?0f)0t2bI?$71$qv{0g#aBC?SeMlFfeR%Uc;Ok-)Mn z+hcp)n=!w=K4kyNGRw*7r3w7T^2di8ZHzWv#UcdntS_qdpxdjgSCTUprn8w+NhDkx z$wij)tBYOj0?r~OXk^ID-OKcyv8VGfPh(0#toGAoB~SKJDL8tJtyQn8`_~z&51^m< za}rr5cwpXzd7*{m@@S`n22z{r{kOSi?2Iw=d@xqb%0*v!DRJ74WmZ^zc|6Ru!;OiO zu)MTD52qE?2;o~Ln+%+q1JF+w<+#6vEXigF=l~37tH>q_mva?JyWwI-Ct z!3V1bFlx{#C!y>>VUq(T>6e;hy?l8#U#%;O2g8wyBl3&&0+x=tofd4pe6-%Q%-CMoCWKI?2^nMG X${8F{4!C|H00000NkvXXu0mjf_DJG; literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/refined_radiance_cube.png b/src/main/resources/assets/create/textures/item/refined_radiance_cube.png new file mode 100644 index 0000000000000000000000000000000000000000..e07427beb3c4d01d34bb50aafabe81721a00fe5e GIT binary patch literal 497 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0ftFLK~y+TrIS5R z!cZ86Peq_W42zA4ny8chE=@>Gbn*wNgSs&gl*Gls!9U{Q;6NNS5HT`ox$RA_z!<|kEV%7VO!JG8+~EW>0u0w=Fj;AUG&6)g!INQh>_%sm z+LNz=Rp)cZXZyURx}ZYlut~E;j9g6*37H)u6%#+UJhL}9ng|I63|ZTMWrtvZ=B^Fc z$@w@Wbcjt=Ml!k#eW=rJ#&oys{pKosMA&{mu1|F+x^$3%TH zK9`HobQQHXnb&&o0Mq=&?Og$qBtcO=(b8pqH&Urqf?-*xRx21}y@4GZIOIO^{TN~Kq5-4ASSt|BR>kxogx)+6vM8|?Jr2${?wbhC?%wQW2W?-7m0kV>TO zog&ERFL`AyTd)x>kRw>nhSqRJ$#^q00000NkvXXu0mjfNPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0l`T`K~y+TrIJlc z8&MR7pE1K^k~DshprBTYsEH^P1l_t6q4)#3s}Q7%E~QW^CFsIG;7SnOh#MCQq8k^L zRs_EgX^Ta$QPf~-NQ_CwRA;=COoHPFqCPO(J9p0e&N=5E$uJC_Ly5IMnFli%?fZ}m zi0nlenwybwhu65%pdc~{bykC?6fQ0Ze;VV<_NL9mW>64@-gb!MWU&*mE-z&NLv&Y| z7=#DLZ6?JYnBq{Imrzdt(pm9nkP$*t?C^lDh-eq@x@rgqUKjsrYvTTobvXPBZXd+{ z!Jpr-w@Y^QD+g;!tjte=mgZL?ZYgdUq*Nb2w>IGT0M1TX{=Ue<+$?ADV~%18k%?1O zrCZT?YzC6zMt)H#P9?r=?O-@$8f(P6KtE3)E24}W6b;O4lJrZ;R29@x+JnusG&E3N zRzc=mC)gOof0;z`_$@^qTLw+RR;pgrLtPVbO(U7kkUWiv?x)D4PIy^cNB_i{6`jYt zt0Gz1f#McvI#rzIUS!Eng`P%pDD)0b=VB(Kk^AT1b9aw1`2G!&(@i3JNZ-d1>&tCn ufm@Sknwaa(#^$}E>)biYkHOZ&#{*X$*QO1S)5ui-0000Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0eMM8K~y+TWBmXB zKLaIz2}+X<2pX_DAq}q+@fxsi^7Q|q&hjXRpc{zO0FY)UQxOJ+-#-~{fBXm*TT)r~ zKeRjo#Sr{nxP6m>K|&tP1Q{3;@5;b%<~W!S1NaRvv0`9&d7r_;$$`Ns+J)iC-aRNT z0s#~QU`_)&-&~U6-Tu7{PrfmOy4#U2?zZgz`=7Y#10k{EDQj!d;YCxMn;PO=l20kGO`_o5;eUJV! zI0c!2U82g*&(Ibajv5OvKd+v!5-bP?pWcDJ(6;m#H~>N5{h@;l!p4T+K!pLY0bu8U z{KXLJqs?$)-vO`$3fQ-e;q8_!4Cg`N0W=Kc5|}ICfd~_j(@Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0dz@3K~y+TV`Lx! z%u37o5290NP6q2^WW=NW|NsAB3yMw#v;bS; zGix!!u}W8l%E~+j^EsDAK$=&+e8fo506#z1|BU|U7|ON$z z2t!IrKEvzRKfr1)Tv!E`g8`f_0BJTgbwSaL4PZ3@X7i*;^>{Ud01K1`gC>*R;P_)S z?IdV33}Cnb6xxSMm5I^}0&oKi4K@DXP+JNQZDIl37Be${u=9WYV#jMUYAi4?000xr VyeanN7$5)u002ovPDHLkV1m$1$#?(& literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/rose_quartz_pickaxe.png b/src/main/resources/assets/create/textures/item/rose_quartz_pickaxe.png new file mode 100644 index 0000000000000000000000000000000000000000..0a1b39cd420783a1eea6ed161825bbf4e49d5ef0 GIT binary patch literal 527 zcmV+q0`UEbP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!TLE5Y-jERYLVDYP0FEX%zMWFy)vpd7ZcXB57-xzrK-Z2PC zK4(zWdjypF|3pHT!O&0%YycdHQ(j^SW?(ZV(eDj!~@^}GAb8>PB!#h0(Fh8PjN({sOOR69?UIUs;cK-)qQ&Sg) zl$3mi*ROvt_LRScNWOb63!(_Rz-QKChC`*wV9g+Y*Y&@Q>glx%3|~G8gZMZN06Ck{ z{~SZPmLF6E0_yAMfL-+H%t2ldAFBZ{KTn!e&#;>#gb{?HQVhqB9|qH98z1tleEEnG zB_V+TNHemZp~7&md-o!c*#F%?%^*IC3y^KbrWppHhJXRs1)z`y(Tt{@IBmuS;4VN9 zZEWED`IX>Q3d114WN4`I|AyL9jL^mgK)DqegT-JO;@2;Bg3boH02MGW000kd*eyX7 ROh5nt002ovPDHLkV1nij;YI)e literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/rose_quartz_shovel.png b/src/main/resources/assets/create/textures/item/rose_quartz_shovel.png new file mode 100644 index 0000000000000000000000000000000000000000..737482446f502858187399f038cef5bdbfb76d37 GIT binary patch literal 489 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0e(qDK~y+TWBmXB zKLaUXc6u&cL+Z@Qj0_+H@Zq|;+5bTp#GaLw^Z);)lNW&a*8ccZgW7XLprC-w@%^&{*I$2Wsq@eQPgpcj&o>cI-;6?)$UYGz^h@c!Ss z*Dt>d*?9ek2+ude>jD_i)U;qo>ffpk)XWIf{0pf08%Xnt7Y`X33=G0hFwF1B*v!oT ze^=MG{~#LZ_w%qY0b#5zFfK?gX)z|YV1KcoLShH@=Gs0ahYuV3tpAcH1Ns%O}>Yat^@ zj0G%%20)sVlS3F%Qt}yIbA*5uA_JIa5WsK&NHfTfV9l?8z!jo<4F*sQfY}UkBC=)} zIDdX6l!X9bFEp9#28Sr4X(xuwgaF(Hu+Sz&GYBvl8fyH%p|%tyv`GPspwtCofT9R2 ff(KxR0Rsa7=E>Lcb(+2m00000NkvXXu0mjfg>KJA literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/create/textures/item/rose_quartz_sword.png b/src/main/resources/assets/create/textures/item/rose_quartz_sword.png new file mode 100644 index 0000000000000000000000000000000000000000..6973445619f33dedd4181b5cd230708940b59a9f GIT binary patch literal 508 zcmVPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0g*{WK~y+TWBmXB zKLe>?c6u&C6UYEk@T|0)|Nk$Yy!C%&@AYtTx&KU1bBF>Un^SXQZ!;X<{QuqU8^6GU z*lfXup*COmKeOiM+m_UeAlpIWSQVpVT$(|c!N4F4j6s~by4n9h7$ynA_%wqs+yIcq zXU`u0KXc~6e^=Kyup&a5L6{Mw83fLsU&-L+77vad85sozOV)P`zyP}l3^2}juV4Pi zn!Ho*rlbWUNF6eO8z3sm0kk;+%+|OS4W@lfvu^`6e+Ow^@!}yPSP%`cKxu~8uYWLJ zzkUMj0u5#c2A^4r8OpT$R3E*UVSs5iGz04 zH)N=|3Y zrY;OADfwXUfMucJ?Abq17AAnZ0OaRGrOI&4zkabZu30k^OoLp6ZYT^e85(N*zoE7i y?q_5G(hQ<;X$ApCGc$j1$io!l1DIjJzyJWrdtAymApi#e00002%$ak(f6mNc`*nVH zv7{piH41Sf3`q)MYQYbG=5V9$+Ab-Vjw!Qe*Bnl`@!Na2x zmT-_n2Btj>vOt>f%n}Z9B?eQeb#&qJa-1XHZic&ecV$5LB z@8h7f54Eqc)0}ydL39X2UwKN`0BNx4>cHu9-U4V z>wuax8VWdKBUi{l%==%d=_)jBz`#|QDi(wazlpx~IvKES0{#G>1FQq|8WC&h!#0J^+6*nK^UL_s^LbtiR4q z&s{o#a7Bq=j%gWiEgnb5hq$|~WAG!d)WB!ihr$P#or3T!J02PWI&NREx^#Admx%L|mmN_54T z!JyyAc6kd*UuCD+^Av;V;0ezTcxuWp=UPDgF&K_5D2i_qLUc{R`h5-WA3e0*o`Y&% z(Oqa;C)Fwz&VLkwAVCy27(mtSv|$(qEIS3qal99rU^4q+Y^(z}X~LWVzLXpR3uMKUeLf5tE zbgEbf)TGgnkt7!K#XN+9|COqyKvf3}T!yJ)L8$PX=o@SQ1=dZ#FZFS*1Nt0dIsgCw M07*qoM6N<$f)9kctN;K2