package com.rwtema.funkylocomotion.blocks; import com.google.common.collect.ImmutableList; import com.mojang.authlib.GameProfile; import com.rwtema.funkylocomotion.api.IAdvStickyBlock; import com.rwtema.funkylocomotion.api.IMoveCheck; import net.minecraft.block.state.IBlockState; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.Iterator; public class TileFrameProjector extends TileEntity implements IAdvStickyBlock, IMoveCheck { public final static int MAX_RANGE = 16; public int range; public EnumFacing facing; public boolean powered = true; public TileFrameProjector(EnumFacing facing) { this(); this.facing = facing; } public TileFrameProjector() { super(); } @Nonnull @Override public NBTTagCompound writeToNBT(NBTTagCompound tag) { super.writeToNBT(tag); tag.setInteger("Facing", facing.ordinal()); tag.setInteger("Range", range); tag.setBoolean("Powered", powered); return tag; } @Override public void readFromNBT(NBTTagCompound tag) { facing = EnumFacing.values()[tag.getInteger("Facing")]; range = tag.getInteger("Range"); powered = tag.getBoolean("Powered"); super.readFromNBT(tag); } @Override public Iterable<BlockPos> getBlocksToMove(World world, BlockPos pos) { if (!powered) return ImmutableList.of(); final int range = this.range; if (range <= 0) return ImmutableList.of(); final BlockPos center = this.pos; final EnumFacing facing = this.facing; if (center == null || facing == null) return ImmutableList.of(); final EnumFacing.Axis axis = facing.getAxis(); if (range <= 0) return ImmutableList.of(); return () -> new Iterator<BlockPos>() { int r = range; Iterator<BlockPos.MutableBlockPos> curIterator; @Override public boolean hasNext() { if (curIterator != null) { if (curIterator.hasNext()) { return true; } } if (r == 0) return false; BlockPos a = center.offset(facing, r); int dx = axis != EnumFacing.Axis.X ? r : 0; int dy = axis != EnumFacing.Axis.Y ? r : 0; int dz = axis != EnumFacing.Axis.Z ? r : 0; curIterator = BlockPos.getAllInBoxMutable( a.add(-dx, -dy, -dz), a.add(dx, dy, dz) ).iterator(); r--; return true; } @Override public BlockPos next() { return curIterator.next(); } }; } @Nonnull @Override public NBTTagCompound getUpdateTag() { NBTTagCompound tag = super.getUpdateTag(); tag.setInteger("Range", range); if (facing != null) tag.setInteger("Facing", facing.ordinal()); tag.setBoolean("Powered", powered); return tag; } @Override public void handleUpdateTag(@Nonnull NBTTagCompound tag) { range = tag.getInteger("Range"); facing = EnumFacing.values()[tag.getInteger("Facing")]; powered = tag.getBoolean("Powered"); } @Nullable @Override public SPacketUpdateTileEntity getUpdatePacket() { return new SPacketUpdateTileEntity(this.pos, 0, this.getUpdateTag()); } @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity pkt) { handleUpdateTag(pkt.getNbtCompound()); } @Override public EnumActionResult canMove(World worldObj, BlockPos pos, @Nullable GameProfile profile) { return range == 0 ? EnumActionResult.FAIL : EnumActionResult.PASS; } @Nonnull @Override public AxisAlignedBB getRenderBoundingBox() { return INFINITE_EXTENT_AABB; } @Override public boolean shouldRefresh(World world, BlockPos pos, @Nonnull IBlockState oldState, @Nonnull IBlockState newSate) { return oldState.getBlock() != newSate.getBlock(); } @Override public boolean shouldRenderInPass(int pass) { return powered && super.shouldRenderInPass(pass); } }