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
This commit is contained in:
simibubi 2019-09-05 02:16:44 +02:00
parent 9420d874fe
commit a62dc492d5
48 changed files with 1272 additions and 55 deletions

View file

@ -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.economy.ShopShelfBlock;
import com.simibubi.create.modules.gardens.CocoaLogBlock; import com.simibubi.create.modules.gardens.CocoaLogBlock;
import com.simibubi.create.modules.logistics.block.BeltFunnelBlock; 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.ExtractorBlock;
import com.simibubi.create.modules.logistics.block.FlexcrateBlock; import com.simibubi.create.modules.logistics.block.FlexcrateBlock;
import com.simibubi.create.modules.logistics.block.LinkedExtractorBlock; import com.simibubi.create.modules.logistics.block.LinkedExtractorBlock;
@ -107,6 +108,7 @@ public enum AllBlocks {
EXTRACTOR(new ExtractorBlock()), EXTRACTOR(new ExtractorBlock()),
LINKED_EXTRACTOR(new LinkedExtractorBlock()), LINKED_EXTRACTOR(new LinkedExtractorBlock()),
BELT_FUNNEL(new BeltFunnelBlock()), BELT_FUNNEL(new BeltFunnelBlock()),
ENTITY_DETECTOR(new EntityDetectorBlock()),
// Symmetry // Symmetry
SYMMETRY_PLANE(new PlaneSymmetryBlock()), SYMMETRY_PLANE(new PlaneSymmetryBlock()),

View file

@ -39,16 +39,18 @@ public enum AllItems {
PLACEMENT_HANDGUN( PLACEMENT_HANDGUN(
new BuilderGunItem(new Properties().setTEISR(() -> () -> renderUsing(AllItemRenderers.BUILDER_GUN)))), new BuilderGunItem(new Properties().setTEISR(() -> () -> renderUsing(AllItemRenderers.BUILDER_GUN)))),
ANDESITE_ALLOY_CUBE(new Item(standardProperties())), ANDESITE_ALLOY_CUBE(new Item(standardProperties())), BLAZE_BRASS_CUBE(new Item(standardProperties())),
BLAZE_BRASS_CUBE(new Item(standardProperties())),
CHORUS_CHROME_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))), CHORUS_CHROME_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))),
CHROMATIC_COMPOUND_CUBE(new ChromaticCompoundCubeItem(standardProperties().rarity(Rarity.UNCOMMON))), CHROMATIC_COMPOUND_CUBE(new ChromaticCompoundCubeItem(standardProperties().rarity(Rarity.UNCOMMON))),
SHADOW_STEEL_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))), SHADOW_STEEL_CUBE(new Item(standardProperties().rarity(Rarity.UNCOMMON))),
ROSE_QUARTZ(new Item(standardProperties())), REFINED_ROSE_QUARTZ(new Item(standardProperties())),
REFINED_RADIANCE_CUBE(new Item(standardProperties())),
BLAZING_PICKAXE(new Item(standardProperties())), BLAZING_PICKAXE(new Item(standardProperties())), BLAZING_SHOVEL(new Item(standardProperties())),
BLAZING_SHOVEL(new Item(standardProperties())), BLAZING_AXE(new Item(standardProperties())), BLAZING_SWORD(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())), TREE_FERTILIZER(new TreeFertilizerItem(standardProperties())),

View file

@ -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.contraptions.relays.belt.BeltTileEntityRenderer;
import com.simibubi.create.modules.economy.ShopShelfTileEntity; import com.simibubi.create.modules.economy.ShopShelfTileEntity;
import com.simibubi.create.modules.logistics.block.BeltFunnelTileEntity; 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.ExtractorTileEntity;
import com.simibubi.create.modules.logistics.block.ExtractorTileEntityRenderer;
import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity; import com.simibubi.create.modules.logistics.block.FlexcrateTileEntity;
import com.simibubi.create.modules.logistics.block.LinkedExtractorTileEntity; 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.LinkedTileEntityRenderer;
import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity; import com.simibubi.create.modules.logistics.block.RedstoneBridgeTileEntity;
import com.simibubi.create.modules.logistics.block.StockswitchTileEntity; 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), MOTOR(MotorTileEntity::new, AllBlocks.MOTOR), GEARBOX(GearboxTileEntity::new, AllBlocks.GEARBOX),
TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE), TURNTABLE(TurntableTileEntity::new, AllBlocks.TURNTABLE),
ENCASED_SHAFT(EncasedShaftTileEntity::new, AllBlocks.ENCASED_SHAFT, AllBlocks.ENCASED_BELT), ENCASED_SHAFT(EncasedShaftTileEntity::new, AllBlocks.ENCASED_SHAFT, AllBlocks.ENCASED_BELT),
ENCASED_FAN(EncasedFanTileEntity::new, AllBlocks.ENCASED_FAN), ENCASED_FAN(EncasedFanTileEntity::new, AllBlocks.ENCASED_FAN), CLUTCH(ClutchTileEntity::new, AllBlocks.CLUTCH),
CLUTCH(ClutchTileEntity::new, AllBlocks.CLUTCH), GEARSHIFT(GearshiftTileEntity::new, AllBlocks.GEARSHIFT), BELT(BeltTileEntity::new, AllBlocks.BELT),
GEARSHIFT(GearshiftTileEntity::new, AllBlocks.GEARSHIFT),
BELT(BeltTileEntity::new, AllBlocks.BELT),
MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON), MECHANICAL_PISTON(MechanicalPistonTileEntity::new, AllBlocks.MECHANICAL_PISTON, AllBlocks.STICKY_MECHANICAL_PISTON),
DRILL(DrillTileEntity::new, AllBlocks.DRILL), DRILL(DrillTileEntity::new, AllBlocks.DRILL),
CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL), CRUSHING_WHEEL(CrushingWheelTileEntity::new, AllBlocks.CRUSHING_WHEEL),
@ -74,10 +76,10 @@ public enum AllTileEntities {
// Logistics // Logistics
REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE), REDSTONE_BRIDGE(RedstoneBridgeTileEntity::new, AllBlocks.REDSTONE_BRIDGE),
STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH), STOCKSWITCH(StockswitchTileEntity::new, AllBlocks.STOCKSWITCH),
FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), FLEXCRATE(FlexcrateTileEntity::new, AllBlocks.FLEXCRATE), EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR),
EXTRACTOR(ExtractorTileEntity::new, AllBlocks.EXTRACTOR),
LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR), LINKED_EXTRACTOR(LinkedExtractorTileEntity::new, AllBlocks.LINKED_EXTRACTOR),
BELT_FUNNEL(BeltFunnelTileEntity::new, AllBlocks.BELT_FUNNEL), BELT_FUNNEL(BeltFunnelTileEntity::new, AllBlocks.BELT_FUNNEL),
ENTITY_DETECTOR(EntityDetectorTileEntity::new, AllBlocks.ENTITY_DETECTOR),
// Economy // Economy
SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF), SHOP_SHELF(ShopShelfTileEntity::new, AllBlocks.SHOP_SHELF),
@ -125,7 +127,9 @@ public enum AllTileEntities {
bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer()); bind(CrushingWheelTileEntity.class, new KineticTileEntityRenderer());
bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer()); bind(WaterWheelTileEntity.class, new KineticTileEntityRenderer());
bind(RedstoneBridgeTileEntity.class, new LinkedTileEntityRenderer()); 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) @OnlyIn(Dist.CLIENT)

View file

@ -15,10 +15,12 @@ import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.World;
public enum AllBeltAttachments { public enum AllBeltAttachments {
BELT_FUNNEL(AllBlocks.BELT_FUNNEL), BELT_FUNNEL(AllBlocks.BELT_FUNNEL),
BELT_OBSERVER(AllBlocks.ENTITY_DETECTOR),
; ;
@ -29,7 +31,7 @@ public enum AllBeltAttachments {
} }
public interface IBeltAttachment { public interface IBeltAttachment {
public Optional<BlockPos> getValidAttachmentFor(BeltTileEntity te); public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te);
public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state); public Optional<BlockPos> getValidBeltPositionFor(IWorld world, BlockPos pos, BlockState state);
@ -80,10 +82,19 @@ public enum AllBeltAttachments {
public void findAttachments(BeltTileEntity belt) { public void findAttachments(BeltTileEntity belt) {
for (AllBeltAttachments ba : AllBeltAttachments.values()) { for (AllBeltAttachments ba : AllBeltAttachments.values()) {
Optional<BlockPos> validAttachmentFor = ba.attachment.getValidAttachmentFor(belt); List<BlockPos> attachmentPositions = ba.attachment.getPotentialAttachmentLocations(belt);
if (validAttachmentFor.isPresent()) { World world = belt.getWorld();
BlockPos pos = validAttachmentFor.get(); for (BlockPos potentialPos : attachmentPositions) {
addAttachment(belt.getWorld(), pos); if (!world.isBlockPresent(potentialPos))
continue;
BlockState state = world.getBlockState(potentialPos);
if (!(state.getBlock() instanceof IBeltAttachment))
continue;
Optional<BlockPos> validBeltPos = ((IBeltAttachment) state.getBlock()).getValidBeltPositionFor(world, potentialPos, state);
if (!validBeltPos.isPresent())
continue;
if (validBeltPos.get().equals(belt.getPos()))
addAttachment(world, potentialPos);
} }
} }
} }

View file

@ -134,13 +134,13 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn
passengers.forEach((entity, info) -> { passengers.forEach((entity, info) -> {
if (!canTransport(entity)) if (!canTransport(entity))
toRemove.add(entity); toRemove.add(entity);
if (info.ticksSinceLastCollision > 0) { if (info.ticksSinceLastCollision > 1) {
toRemove.add(entity); toRemove.add(entity);
} }
info.tick(); info.tick();
}); });
toRemove.forEach(e -> { toRemove.forEach(e -> {
if (e instanceof ItemEntity) if (e instanceof ItemEntity && ((ItemEntity) e).getAge() < 0)
((ItemEntity) e).setAgeToCreativeDespawnTime(); ((ItemEntity) e).setAgeToCreativeDespawnTime();
passengers.remove(e); passengers.remove(e);
}); });
@ -188,8 +188,10 @@ public class BeltTileEntity extends KineticTileEntity implements ITickableTileEn
BeltTileEntity belt = (BeltTileEntity) te; BeltTileEntity belt = (BeltTileEntity) te;
for (BeltAttachmentState state : belt.attachmentTracker.attachments) { for (BeltAttachmentState state : belt.attachmentTracker.attachments) {
if (state.attachment.handleEntity(belt, entityIn, state)) if (state.attachment.handleEntity(belt, entityIn, state)) {
info.ticksSinceLastCollision--;
return; return;
}
} }
final Direction beltFacing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); 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))) .grow(-Math.abs(checkDistance.x), -Math.abs(checkDistance.y), -Math.abs(checkDistance.z)))
.isEmpty()) { .isEmpty()) {
entityIn.setMotion(0, 0, 0); entityIn.setMotion(0, 0, 0);
info.ticksSinceLastCollision--;
return; return;
} }
} }

View file

@ -1,5 +1,7 @@
package com.simibubi.create.modules.logistics.block; package com.simibubi.create.modules.logistics.block;
import java.util.Arrays;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import com.simibubi.create.AllBlocks; 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.foundation.utility.VecHelper;
import com.simibubi.create.modules.contraptions.relays.belt.AllBeltAttachments.BeltAttachmentState; 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.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 com.simibubi.create.modules.contraptions.relays.belt.BeltTileEntity;
import net.minecraft.block.Block; import net.minecraft.block.Block;
@ -113,13 +117,8 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
} }
@Override @Override
public Optional<BlockPos> getValidAttachmentFor(BeltTileEntity te) { public List<BlockPos> getPotentialAttachmentLocations(BeltTileEntity te) {
BlockPos validPos = te.getPos().up(); return Arrays.asList(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);
} }
@Override @Override
@ -136,7 +135,8 @@ public class BeltFunnelBlock extends HorizontalBlock implements IBeltAttachment,
public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) { public boolean handleEntity(BeltTileEntity te, Entity entity, BeltAttachmentState state) {
if (!(entity instanceof ItemEntity)) if (!(entity instanceof ItemEntity))
return false; 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; return false;
entity.setMotion(Vec3d.ZERO); entity.setMotion(Vec3d.ZERO);

View file

@ -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<EntityDetectorTileEntity>, IBeltAttachment, IBlockWithFilter {
public static BooleanProperty POWERED = BlockStateProperties.POWERED;
public static BooleanProperty BELT = BooleanProperty.create("belt");
private static final List<Vec3d> 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<Block, BlockState> 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<BlockPos> 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<BlockPos> 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);
}
}

View file

@ -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;
}
}

View file

@ -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<EntityDetectorTileEntity> {
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);
}
}

View file

@ -1,5 +1,10 @@
package com.simibubi.create.modules.logistics.block; 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.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@ -12,8 +17,10 @@ import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; 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.ISelectionContext;
import net.minecraft.util.math.shapes.VoxelShape; import net.minecraft.util.math.shapes.VoxelShape;
import net.minecraft.util.math.shapes.VoxelShapes; 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.IWorldReader;
import net.minecraft.world.World; 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 BooleanProperty POWERED = BlockStateProperties.POWERED;
public static final VoxelShape SHAPE_NORTH = makeCuboidShape(4, 2, -1, 12, 10, 5), 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_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); SHAPE_EAST = makeCuboidShape(11, 2, 4, 17, 10, 12);
private static final List<Vec3d> itemPositions = new ArrayList<>(Direction.values().length);
public ExtractorBlock() { public ExtractorBlock() {
super(Properties.from(Blocks.ANDESITE)); super(Properties.from(Blocks.ANDESITE));
setDefaultState(getDefaultState().with(POWERED, false)); setDefaultState(getDefaultState().with(POWERED, false));
cacheItemPositions();
} }
@Override @Override
@ -52,7 +61,7 @@ public class ExtractorBlock extends HorizontalBlock {
@Override @Override
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
return false; return handleActivatedFilterSlots(state, worldIn, pos, player, handIn, hit);
} }
@Override @Override
@ -71,6 +80,8 @@ public class ExtractorBlock extends HorizontalBlock {
@Override @Override
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) { public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
updateObservedInventory(state, worldIn, pos); updateObservedInventory(state, worldIn, pos);
cacheItemPositions();
} }
@Override @Override
@ -125,4 +136,43 @@ public class ExtractorBlock extends HorizontalBlock {
return VoxelShapes.empty(); 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();
}
} }

View file

@ -3,15 +3,18 @@ package com.simibubi.create.modules.logistics.block;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.foundation.block.SyncedTileEntity; 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.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraftforge.common.util.LazyOptional; import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler; 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 State state;
private ItemStack filter;
private int cooldown; private int cooldown;
private LazyOptional<IItemHandler> inventory; private LazyOptional<IItemHandler> inventory;
private boolean initialize; private boolean initialize;
@ -20,6 +23,7 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
super(AllTileEntities.EXTRACTOR.type); super(AllTileEntities.EXTRACTOR.type);
state = State.WAITING_FOR_INVENTORY; state = State.WAITING_FOR_INVENTORY;
inventory = LazyOptional.empty(); inventory = LazyOptional.empty();
filter = ItemStack.EMPTY;
} }
@Override @Override
@ -27,6 +31,18 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
return state; 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 @Override
public void onLoad() { public void onLoad() {
initialize = true; initialize = true;
@ -68,4 +84,15 @@ public class ExtractorTileEntity extends SyncedTileEntity implements IExtractor,
this.inventory = inventory; this.inventory = inventory;
} }
@Override
public void setFilter(ItemStack stack) {
filter = stack;
sendData();
}
@Override
public ItemStack getFilter() {
return filter;
}
} }

View file

@ -0,0 +1,20 @@
package com.simibubi.create.modules.logistics.block;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
public class ExtractorTileEntityRenderer extends TileEntityRenderer<ExtractorTileEntity> {
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);
}
}

View file

@ -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 <T extends TileEntity & IHaveFilter> 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();
}
}

View file

@ -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();
}
}

View file

@ -15,6 +15,7 @@ import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult; import net.minecraft.util.math.BlockRayTraceResult;
@ -30,13 +31,14 @@ import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
public interface IBlockWithFrequency { public interface IBlockWithFrequency {
public Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state); public Pair<Vec3d, Vec3d> getFrequencyItemPositions(BlockState state);
public Direction getFrequencyItemFacing(BlockState state); public Direction getFrequencyItemFacing(BlockState state);
public default float getItemHitboxScale() { public default float getItemHitboxScale() {
return 2 / 16f; 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) { Hand handIn, BlockRayTraceResult hit) {
TileEntity te = worldIn.getTileEntity(pos); TileEntity te = worldIn.getTileEntity(pos);
if (te == null || !(te instanceof IHaveWireless)) if (te == null || !(te instanceof IHaveWireless))
@ -87,6 +89,7 @@ public interface IBlockWithFrequency {
Vec3d first = positions.getLeft().add(vec); Vec3d first = positions.getLeft().add(vec);
Vec3d second = positions.getRight().add(vec); Vec3d second = positions.getRight().add(vec);
float scale = freqBlock.getItemHitboxScale(); float scale = freqBlock.getItemHitboxScale();
Direction facing = freqBlock.getFrequencyItemFacing(state);
AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(scale); AxisAlignedBB firstBB = new AxisAlignedBB(first, first).grow(scale);
AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(scale); AxisAlignedBB secondBB = new AxisAlignedBB(second, second).grow(scale);
@ -100,7 +103,8 @@ public interface IBlockWithFrequency {
GlStateManager.depthMask(false); GlStateManager.depthMask(false);
GlStateManager.matrixMode(5889); GlStateManager.matrixMode(5889);
if (firstBB.contains(result.getHitVec())) { boolean firstContains = firstBB.contains(result.getHitVec());
if (firstContains) {
GlStateManager.lineWidth(2); GlStateManager.lineWidth(2);
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f); WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), 1, 1, .5f, 1f);
} else { } else {
@ -108,7 +112,8 @@ public interface IBlockWithFrequency {
WorldRenderer.drawSelectionBoundingBox(firstBB.grow(1 / 128f), .5f, .5f, .2f, 1f); 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); GlStateManager.lineWidth(2);
WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f); WorldRenderer.drawSelectionBoundingBox(secondBB.grow(1 / 128f), 1, 1, .5f, 1f);
} else { } else {
@ -119,6 +124,49 @@ public interface IBlockWithFrequency {
GlStateManager.matrixMode(5888); GlStateManager.matrixMode(5888);
GlStateManager.depthMask(true); GlStateManager.depthMask(true);
GlStateManager.enableTexture(); 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.disableBlend();
GlStateManager.lineWidth(1); GlStateManager.lineWidth(1);
TessellatorHelper.cleanUpAfterDrawing(); TessellatorHelper.cleanUpAfterDrawing();

View file

@ -44,9 +44,15 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
boolean hasInventory = getInventory().isPresent(); boolean hasInventory = getInventory().isPresent();
ItemStack toExtract = ItemStack.EMPTY; ItemStack toExtract = ItemStack.EMPTY;
if (hasSpace && hasInventory) if (hasSpace && hasInventory) {
toExtract = extract(true); 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 (state == State.WAITING_FOR_ENTITY) {
if (hasSpace) if (hasSpace)
setState(State.RUNNING); setState(State.RUNNING);
@ -79,8 +85,13 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
boolean hasInventory = getInventory().isPresent(); boolean hasInventory = getInventory().isPresent();
ItemStack toExtract = ItemStack.EMPTY; ItemStack toExtract = ItemStack.EMPTY;
if (hasSpace && hasInventory) if (hasSpace && hasInventory) {
toExtract = extract(true); 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 (getState() == State.WAITING_FOR_INVENTORY) {
if (!hasInventory) { if (!hasInventory) {
@ -101,9 +112,11 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
default ItemStack extract(boolean simulate) { default ItemStack extract(boolean simulate) {
IItemHandler inv = getInventory().orElse(null); IItemHandler inv = getInventory().orElse(null);
ItemStack extracting = ItemStack.EMPTY; 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++) { 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(); ItemStack compare = stack.copy();
compare.setCount(extracting.getCount()); compare.setCount(extracting.getCount());
if (!extracting.isEmpty() && !extracting.equals(compare, false)) if (!extracting.isEmpty() && !extracting.equals(compare, false))
@ -116,7 +129,7 @@ public interface IExtractor extends ITickableTileEntity, IInventoryManipulator {
if (!simulate) if (!simulate)
inv.extractItem(slot, stack.getCount(), false); inv.extractItem(slot, stack.getCount(), false);
if (extracting.getCount() >= EXTRACTION_COUNT) if (extracting.getCount() >= extractionCount)
break; break;
} }

View file

@ -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();
}

View file

@ -60,7 +60,7 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr
public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn, public boolean onBlockActivated(BlockState state, World worldIn, BlockPos pos, PlayerEntity player, Hand handIn,
BlockRayTraceResult hit) { BlockRayTraceResult hit) {
return super.onBlockActivated(state, worldIn, pos, player, handIn, 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() { private void cacheItemPositions() {
@ -74,7 +74,7 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
Direction facing = Direction.byHorizontalIndex(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); second = new Vec3d(11.5f / 16f + zFightOffset, 8f / 16f, 14f / 16f);
float angle = facing.getHorizontalAngle(); float angle = facing.getHorizontalAngle();
@ -91,7 +91,7 @@ public class LinkedExtractorBlock extends ExtractorBlock implements IBlockWithFr
@Override @Override
public float getItemHitboxScale() { public float getItemHitboxScale() {
return 3/32f; return 3 / 32f;
} }
@Override @Override

View file

@ -5,6 +5,8 @@ import static net.minecraft.state.properties.BlockStateProperties.POWERED;
import com.simibubi.create.AllTileEntities; import com.simibubi.create.AllTileEntities;
import com.simibubi.create.modules.logistics.IReceiveWireless; 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.state.properties.BlockStateProperties;
import net.minecraft.tileentity.ITickableTileEntity; import net.minecraft.tileentity.ITickableTileEntity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@ -12,11 +14,12 @@ import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.items.IItemHandler; import net.minecraftforge.items.IItemHandler;
public class LinkedExtractorTileEntity extends LinkedTileEntity public class LinkedExtractorTileEntity extends LinkedTileEntity
implements IReceiveWireless, ITickableTileEntity, IExtractor { implements IReceiveWireless, ITickableTileEntity, IExtractor, IHaveFilter {
public boolean receivedSignal; public boolean receivedSignal;
private State state; private State state;
private ItemStack filter;
private int cooldown; private int cooldown;
private LazyOptional<IItemHandler> inventory; private LazyOptional<IItemHandler> inventory;
@ -24,6 +27,7 @@ public class LinkedExtractorTileEntity extends LinkedTileEntity
super(AllTileEntities.LINKED_EXTRACTOR.type); super(AllTileEntities.LINKED_EXTRACTOR.type);
state = State.WAITING_FOR_INVENTORY; state = State.WAITING_FOR_INVENTORY;
inventory = LazyOptional.empty(); inventory = LazyOptional.empty();
filter = ItemStack.EMPTY;
} }
@Override @Override
@ -31,6 +35,18 @@ public class LinkedExtractorTileEntity extends LinkedTileEntity
receivedSignal = 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 @Override
public void tick() { public void tick() {
IExtractor.super.tick(); IExtractor.super.tick();
@ -75,4 +91,15 @@ public class LinkedExtractorTileEntity extends LinkedTileEntity
this.inventory = inventory; this.inventory = inventory;
} }
@Override
public void setFilter(ItemStack stack) {
filter = stack;
sendData();
}
@Override
public ItemStack getFilter() {
return filter;
}
} }

View file

@ -0,0 +1,23 @@
package com.simibubi.create.modules.logistics.block;
import net.minecraft.client.renderer.tileentity.TileEntityRenderer;
public class LinkedExtractorTileEntityRenderer extends TileEntityRenderer<LinkedExtractorTileEntity> {
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);
}
}

View file

@ -23,8 +23,6 @@ public class LinkedTileEntityRenderer extends TileEntityRenderer<LinkedTileEntit
@Override @Override
public void render(LinkedTileEntity tileEntityIn, double x, double y, double z, float partialTicks, public void render(LinkedTileEntity tileEntityIn, double x, double y, double z, float partialTicks,
int destroyStage) { int destroyStage) {
super.render(tileEntityIn, x, y, z, partialTicks, destroyStage);
BlockState state = tileEntityIn.getBlockState(); BlockState state = tileEntityIn.getBlockState();
IBlockWithFrequency block = (IBlockWithFrequency) state.getBlock(); IBlockWithFrequency block = (IBlockWithFrequency) state.getBlock();
Direction facing = block.getFrequencyItemFacing(state); Direction facing = block.getFrequencyItemFacing(state);

View file

@ -158,7 +158,7 @@ public class RedstoneBridgeBlock extends ProperDirectionalBlock implements ITool
return true; return true;
} }
return handleActivated(state, worldIn, pos, player, handIn, hit); return handleActivatedFrequencySlots(state, worldIn, pos, player, handIn, hit);
} }
@Override @Override

View file

@ -0,0 +1,23 @@
{
"variants": {
"powered=false,belt=false,facing=south": { "model": "create:block/entity_detector", "y": 0 },
"powered=false,belt=false,facing=east": { "model": "create:block/entity_detector", "y": 270 },
"powered=false,belt=false,facing=north": { "model": "create:block/entity_detector", "y": 180 },
"powered=false,belt=false,facing=west": { "model": "create:block/entity_detector", "y": 90 },
"powered=true,belt=false,facing=south": { "model": "create:block/entity_detector_powered", "y": 0 },
"powered=true,belt=false,facing=east": { "model": "create:block/entity_detector_powered", "y": 270 },
"powered=true,belt=false,facing=north": { "model": "create:block/entity_detector_powered", "y": 180 },
"powered=true,belt=false,facing=west": { "model": "create:block/entity_detector_powered", "y": 90 },
"powered=false,belt=true,facing=south": { "model": "create:block/entity_detector_with_belt", "y": 0 },
"powered=false,belt=true,facing=east": { "model": "create:block/entity_detector_with_belt", "y": 270 },
"powered=false,belt=true,facing=north": { "model": "create:block/entity_detector_with_belt", "y": 180 },
"powered=false,belt=true,facing=west": { "model": "create:block/entity_detector_with_belt", "y": 90 },
"powered=true,belt=true,facing=south": { "model": "create:block/entity_detector_with_belt_powered", "y": 0 },
"powered=true,belt=true,facing=east": { "model": "create:block/entity_detector_with_belt_powered", "y": 270 },
"powered=true,belt=true,facing=north": { "model": "create:block/entity_detector_with_belt_powered", "y": 180 },
"powered=true,belt=true,facing=west": { "model": "create:block/entity_detector_with_belt_powered", "y": 90 }
}
}

View file

@ -12,12 +12,20 @@
"item.create.blueprint": "Schematic", "item.create.blueprint": "Schematic",
"item.create.belt_connector": "Mechanical Belt", "item.create.belt_connector": "Mechanical Belt",
"item.create.filter": "Filter", "item.create.filter": "Filter",
"item.create.rose_quartz": "Rose Quartz",
"item.create.refined_rose_quartz": "Refined Rose Quartz",
"item.create.refined_radiance_cube": "Refined Radiance",
"item.create.blazing_pickaxe": "Blazing Pickaxe", "item.create.blazing_pickaxe": "Blazing Pickaxe",
"item.create.blazing_shovel": "Blazing Shovel", "item.create.blazing_shovel": "Blazing Shovel",
"item.create.blazing_axe": "Blazing Axe", "item.create.blazing_axe": "Blazing Axe",
"item.create.blazing_sword": "Blazing Longsword", "item.create.blazing_sword": "Blazing Longsword",
"item.create.rose_quartz_pickaxe": "Gilded Quartz Pickaxe",
"item.create.rose_quartz_shovel": "Gilded Quartz Shovel",
"item.create.rose_quartz_axe": "Gilded Quartz Axe",
"item.create.rose_quartz_sword": "Gilded Quartz Blade",
"block.create.cogwheel": "Cogwheel", "block.create.cogwheel": "Cogwheel",
"block.create.large_cogwheel": "Large Cogwheel", "block.create.large_cogwheel": "Large Cogwheel",
"block.create.turntable": "Turntable", "block.create.turntable": "Turntable",
@ -51,6 +59,7 @@
"block.create.belt_funnel": "Belt Funnel", "block.create.belt_funnel": "Belt Funnel",
"block.create.linked_extractor": "Linked Extractor", "block.create.linked_extractor": "Linked Extractor",
"block.create.pulse_repeater": "Pulse Repeater", "block.create.pulse_repeater": "Pulse Repeater",
"block.create.entity_detector": "Belt Observer",
"block.create.andesite_bricks": "Andesite Bricks", "block.create.andesite_bricks": "Andesite Bricks",
"block.create.diorite_bricks": "Diorite Bricks", "block.create.diorite_bricks": "Diorite Bricks",

View file

@ -0,0 +1,92 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"parent": "block/block",
"textures": {
"brass_casing": "create:block/brass_casing",
"extractor": "create:block/extractor",
"entity_detector_off": "create:block/entity_detector_off",
"entity_detector_front": "create:block/entity_detector_front",
"particle": "create:block/entity_detector_off"
},
"elements": [
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 90 },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ], "rotation": 180 },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"south": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Center",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 17 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 2, 2, 14, 14 ] },
"east": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"south": { "texture": "#entity_detector_front", "uv": [ 2, 2, 14, 14 ] },
"west": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] }
}
},
{
"name": "Filter",
"from": [ 5, 14, 15 ],
"to": [ 11, 16, 20 ],
"rotation": { "origin": [ 9, 16, 16 ], "axis": "x", "angle": 22.5 },
"faces": {
"north": { "texture": "#entity_detector_off", "uv": [ 5, 14, 11, 16 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 1, 4, 6, 6 ], "rotation": 180 },
"south": { "texture": "#entity_detector_off", "uv": [ 5, 4, 11, 6 ], "rotation": 180 },
"west": { "texture": "#entity_detector_off", "uv": [ 10, 4, 15, 6 ], "rotation": 180 },
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 },
"down": { "texture": "#entity_detector_off", "uv": [ 5, 5, 11, 10 ] }
}
}
]
}

View file

@ -0,0 +1,8 @@
{
"parent": "create:block/entity_detector",
"textures": {
"extractor": "create:block/extractor_powered",
"entity_detector_off": "create:block/entity_detector_on",
"particle": "create:block/entity_detector_on"
}
}

View file

@ -0,0 +1,105 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"parent": "block/block",
"textures": {
"brass_casing": "create:block/brass_casing",
"extractor": "create:block/extractor",
"entity_detector_off": "create:block/entity_detector_off",
"entity_detector_front": "create:block/entity_detector_front",
"particle": "create:block/entity_detector_off"
},
"elements": [
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 90 },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ], "rotation": 180 },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"south": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Center",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 17 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 2, 2, 14, 14 ] },
"east": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"south": { "texture": "#entity_detector_front", "uv": [ 2, 2, 14, 14 ] },
"west": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] }
}
},
{
"name": "Belt Thing",
"from": [ 1, 5, 16 ],
"to": [ 15, 11, 30 ],
"faces": {
"north": { "texture": "#entity_detector_off", "uv": [ 1, 0, 15, 6 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 1, 0, 15, 6 ] },
"south": { "texture": "#entity_detector_off", "uv": [ 1, 0, 15, 6 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 2, 0, 16, 6 ] },
"up": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] },
"down": { "texture": "#brass_casing", "uv": [ 1, 1, 15, 15 ] }
}
},
{
"name": "Filter",
"from": [ 5, 14, 15 ],
"to": [ 11, 16, 20 ],
"rotation": { "origin": [ 9, 16, 16 ], "axis": "x", "angle": 22.5 },
"faces": {
"north": { "texture": "#entity_detector_off", "uv": [ 5, 14, 11, 16 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 1, 4, 6, 6 ], "rotation": 180 },
"south": { "texture": "#entity_detector_off", "uv": [ 5, 4, 11, 6 ], "rotation": 180 },
"west": { "texture": "#entity_detector_off", "uv": [ 10, 4, 15, 6 ], "rotation": 180 },
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 },
"down": { "texture": "#entity_detector_off", "uv": [ 5, 5, 11, 10 ] }
}
}
]
}

View file

@ -0,0 +1,8 @@
{
"parent": "create:block/entity_detector_with_belt",
"textures": {
"extractor": "create:block/extractor_powered",
"entity_detector_off": "create:block/entity_detector_on",
"particle": "create:block/entity_detector_on"
}
}

View file

@ -0,0 +1,83 @@
{
"__comment": "Model generated using MrCrayfish's Model Creator (https://mrcrayfish.com/tools?id=mc)",
"parent": "block/block",
"display": {
"gui": {
"rotation": [ 30, 45, 0 ],
"translation": [ 0, 0, 0],
"scale":[ 0.625, 0.625, 0.625 ]
}
},
"textures": {
"brass_casing": "create:block/brass_casing",
"entity_detector_off": "create:block/entity_detector_off",
"entity_detector_front": "create:block/entity_detector_front"
},
"elements": [
{
"name": "Bottom",
"from": [ 0, 0, 0 ],
"to": [ 16, 2, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 14, 16, 16 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 90 },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Top",
"from": [ 0, 14, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 14, 0, 16, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 2 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 16, 16 ], "rotation": 180 },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 16, 16 ] }
}
},
{
"name": "Side",
"from": [ 0, 2, 0 ],
"to": [ 2, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"east": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"south": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"west": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Side",
"from": [ 14, 2, 0 ],
"to": [ 16, 14, 16 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 0, 2, 2, 14 ] },
"east": { "texture": "#entity_detector_off", "uv": [ 2, 0, 14, 16 ], "rotation": 270 },
"south": { "texture": "#brass_casing", "uv": [ 14, 2, 16, 14 ] },
"west": { "texture": "#brass_casing", "uv": [ 2, 0, 14, 16 ], "rotation": 90 },
"up": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] },
"down": { "texture": "#entity_detector_off", "uv": [ 0, 0, 2, 16 ] }
}
},
{
"name": "Center",
"from": [ 2, 2, 1 ],
"to": [ 14, 14, 17 ],
"faces": {
"north": { "texture": "#brass_casing", "uv": [ 2, 2, 14, 14 ] },
"east": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"south": { "texture": "#entity_detector_front", "uv": [ 2, 2, 14, 14 ] },
"west": { "texture": "#entity_detector_front", "uv": [ 0, 2, 16, 14 ] },
"up": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] },
"down": { "texture": "#brass_casing", "uv": [ 0, 0, 12, 16 ] }
}
}
]
}

View file

@ -1,10 +1,92 @@
{ {
"parent": "create:block/extractor_powered", "parent": "block/block",
"display": { "display": {
"gui": { "gui": {
"rotation": [ 30, 45, 0 ], "rotation": [ 30, 45, 0 ],
"translation": [ 0, 0, 0], "translation": [ 0, 0, 0],
"scale":[ 0.625, 0.625, 0.625 ] "scale":[ 0.625, 0.625, 0.625 ]
} }
} },
"textures": {
"extractor": "create:block/extractor",
"symbols": "create:item/symbols"
},
"elements": [
{
"name": "Indicator",
"from": [ 8, 7, 13 ],
"to": [ 16, 15, 13 ],
"shade": false,
"rotation": { "origin": [ 8, 8, 8 ], "axis": "y", "angle": -45.0 },
"faces": {
"north": { "texture": "#symbols", "uv": [ 0, 0, 8, 8 ] },
"south": { "texture": "#symbols", "uv": [ 0, 0, 8, 8 ] }
}
},
{
"name": "Bottom",
"from": [ 4, 2, -1 ],
"to": [ 12, 3, 5 ],
"faces": {
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
"south": { "texture": "#extractor", "uv": [ 6, 7, 14, 8 ] },
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
"up": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 90 },
"down": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 270 }
}
},
{
"name": "Top",
"from": [ 4, 9, -1 ],
"to": [ 12, 10, 5 ],
"faces": {
"east": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ], "rotation": 180 },
"south": { "texture": "#extractor", "uv": [ 6, 0, 14, 1 ] },
"west": { "texture": "#extractor", "uv": [ 0, 0, 6, 1 ] },
"up": { "texture": "#extractor", "uv": [ 0, 0, 6, 8 ], "rotation": 90 },
"down": { "texture": "#extractor", "uv": [ 9, 0, 15, 8 ], "rotation": 270 }
}
},
{
"name": "Side",
"from": [ 4, 3, -1 ],
"to": [ 5, 9, 5 ],
"faces": {
"east": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ], "rotation": 180 },
"south": { "texture": "#extractor", "uv": [ 6, 1, 7, 7 ] },
"west": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ] }
}
},
{
"name": "Side",
"from": [ 11, 3, -1 ],
"to": [ 12, 9, 5 ],
"faces": {
"east": { "texture": "#extractor", "uv": [ 0, 1, 6, 7 ], "rotation": 180 },
"south": { "texture": "#extractor", "uv": [ 13, 1, 14, 7 ] },
"west": { "texture": "#extractor", "uv": [ 9, 1, 15, 7 ] }
}
},
{
"name": "Center",
"from": [ 5, 3, 3 ],
"to": [ 11, 9, 4 ],
"faces": {
"south": { "texture": "#extractor", "uv": [ 7, 1, 13, 7 ] }
}
},
{
"name": "FilterSpot",
"from": [ 5, 10, -0.6 ],
"to": [ 11, 12, 4 ],
"rotation": { "origin": [ 8, 11, -1 ], "axis": "x", "angle": 22.5 },
"faces": {
"north": { "texture": "#extractor", "uv": [ 13, 1, 15, 7 ], "rotation": 90 },
"east": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ], "rotation": 180 },
"south": { "texture": "#extractor", "uv": [ 4, 1, 5, 7 ], "rotation": 270 },
"west": { "texture": "#extractor", "uv": [ 0.1, 0, 4.7, 2 ] },
"up": { "texture": "#extractor", "uv": [ 0, 9, 5, 15 ], "rotation": 90 }
}
}
]
} }

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/refined_radiance_cube"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/refined_rose_quartz"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/rose_quartz"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/rose_quartz_axe"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/rose_quartz_pickaxe"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/rose_quartz_shovel"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "create:item/rose_quartz_sword"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 497 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 484 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 481 B

After

Width:  |  Height:  |  Size: 479 B