diff --git a/common/src/main/java/common/block/tech/BlockDisplay.java b/common/src/main/java/common/block/tech/BlockDisplay.java index f1762f7c..a9bddd44 100644 --- a/common/src/main/java/common/block/tech/BlockDisplay.java +++ b/common/src/main/java/common/block/tech/BlockDisplay.java @@ -1,10 +1,22 @@ package common.block.tech; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Queue; +import java.util.Set; + +import common.block.Block; import common.block.BlockContainer; import common.block.Material; import common.block.Rotatable; +import common.block.liquid.BlockLiquid; +import common.block.liquid.BlockStaticLiquid; +import common.collect.Sets; import common.entity.npc.EntityNPC; import common.entity.types.EntityLiving; +import common.init.Blocks; import common.item.CheatTab; import common.model.Model; import common.model.ModelProvider; @@ -15,6 +27,9 @@ import common.tileentity.TileEntityDisplay; import common.util.BlockPos; import common.util.BoundingBox; import common.util.Facing; +import common.util.Pair; +import common.util.Vec3i; +import common.world.AWorldServer; import common.world.IWorldAccess; import common.world.State; import common.world.World; @@ -24,9 +39,8 @@ public class BlockDisplay extends BlockContainer implements Rotatable public BlockDisplay() { super(Material.SOLID); - float f = 0.25F; - float f1 = 1.0F; - this.setBlockBounds(0.5F - f, 0.0F, 0.5F - f, 0.5F + f, f1, 0.5F + f); + this.setLightLevel(1.0f); + this.setBlockBounds(0.0F, 0.0F, 1.0F - 0.0625F, 1.0F, 1.0F, 1.0F); this.setDefaultState(this.getBaseState().withProperty(FACING, Facing.NORTH)); this.setTab(CheatTab.TECHNOLOGY); } @@ -112,7 +126,7 @@ public class BlockDisplay extends BlockContainer implements Rotatable } public State onBlockPlaced(World worldIn, BlockPos pos, Facing facing, float hitX, float hitY, float hitZ, EntityLiving placer) { - return this.getState().withProperty(FACING, facing.getAxis().isVertical() ? placer.getHorizontalFacing() : facing); + return this.getState().withProperty(FACING, facing.getAxis().isVertical() ? placer.getHorizontalFacing().getOpposite() : facing); } public int getRenderType() { @@ -132,22 +146,90 @@ public class BlockDisplay extends BlockContainer implements Rotatable public Model getModel(ModelProvider provider, String name, State state) { return provider.getModel("iron_block").add(0, 0, 15, 16, 16, 16).n().noCull().s().du().we().rotate(ModelRotation.getNorthRot(state.getValue(FACING))); } + + private boolean test(World world, BlockPos pos, BlockPos origin, Facing dir) { + int radius = 9; + if(pos.getX() < origin.getX() - radius || pos.getX() > origin.getX() + radius) + return false; + if(pos.getY() < origin.getY() - radius || pos.getY() > origin.getY() + radius) + return false; + if(pos.getZ() < origin.getZ() - radius || pos.getZ() > origin.getZ() + radius) + return false; + State state = world.getState(pos); + return state.getBlock() == this && state.getValue(FACING) == dir; + } + + private Pair getSpan(World world, BlockPos origin) { + State state = world.getState(origin); + if(state.getBlock() != this) + return null; + Facing dir = state.getValue(FACING); + Queue queue = new ArrayDeque(); + Set present = new HashSet(); + Set visited = new HashSet(); + Facing[] dirs = new Facing[] {Facing.UP, Facing.DOWN, dir.rotateY(), dir.rotateYCCW()}; + present.add(origin); + visited.add(origin); - public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) - { - if (!worldIn.client) - { - TileEntity tileentity = worldIn.getTileEntity(pos); - - if (tileentity instanceof TileEntityDisplay display) - { - display.setPixel(1, 12, 0xff0000); - display.setPixel(2, 12, 0x00ff00); - display.setPixel(3, 12, 0x0000ff); - display.markDirty(); - worldIn.markBlockForUpdate(pos); + for(Facing off : dirs) { + BlockPos pos = origin.offset(off); + if(!visited.contains(pos)) { + if(test(world, pos, origin, dir)) + queue.add(pos); + visited.add(pos); + } + } + BlockPos loc; + int minX = origin.getX(); + int minY = origin.getY(); + int minZ = origin.getZ(); + int maxX = origin.getX(); + int maxY = origin.getY(); + int maxZ = origin.getZ(); + while((loc = queue.poll()) != null) { + present.add(loc); + minX = Math.min(minX, loc.getX()); + minY = Math.min(minY, loc.getY()); + minZ = Math.min(minZ, loc.getZ()); + maxX = Math.max(maxX, loc.getX()); + maxY = Math.max(maxY, loc.getY()); + maxZ = Math.max(maxZ, loc.getZ()); + for(Facing off : dirs) { + BlockPos pos = loc.offset(off); + if(!visited.contains(pos)) { + visited.add(pos); + if(test(world, pos, origin, dir)) + queue.add(pos); + } } } - return true; + if(maxX - minX >= 8 || maxY - minY >= 8 || maxZ - minZ >= 8) + return null; + BlockPos min = new BlockPos(minX, minY, minZ); + BlockPos max = new BlockPos(maxX, maxY, maxZ); + for(BlockPos pos : BlockPos.getAllInBox(min, max)) { + if(!present.contains(pos)) + return null; + } + return new Pair(min, max); } + + public boolean onBlockActivated(World worldIn, BlockPos pos, State state, EntityNPC playerIn, Facing side, float hitX, float hitY, float hitZ) { + if(!worldIn.client) { + Pair span = this.getSpan(worldIn, pos); + if(span == null) + return true; + for(BlockPos loc : BlockPos.getAllInBox(span.first(), span.second())) { + TileEntity tileentity = worldIn.getTileEntity(loc); + if(tileentity instanceof TileEntityDisplay display) { + for(int z = 0; z < 16; z++) { + display.setPixel(worldIn.rand.zrange(16), worldIn.rand.zrange(16), worldIn.rand.zrange(0x8000000)); + } + display.markDirty(); + worldIn.markBlockForUpdate(loc); + } + } + } + return true; + } }