diff --git a/src/main/java/appeng/debug/ReplicatorCardItem.java b/src/main/java/appeng/debug/ReplicatorCardItem.java index b3ca0a0b5..80bf41ef7 100644 --- a/src/main/java/appeng/debug/ReplicatorCardItem.java +++ b/src/main/java/appeng/debug/ReplicatorCardItem.java @@ -26,10 +26,12 @@ import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUseContext; import net.minecraft.nbt.CompoundNBT; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResultType; import net.minecraft.util.Direction; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.text.StringTextComponent; import net.minecraft.world.World; import net.minecraft.world.dimension.DimensionType; @@ -48,10 +50,31 @@ public class ReplicatorCardItem extends AEBaseItem { super(properties); } + @Override + public ActionResult onItemRightClick(World worldIn, PlayerEntity playerIn, Hand handIn) { + if (!worldIn.isRemote()) { + final CompoundNBT tag = playerIn.getHeldItem(handIn).getOrCreateTag(); + final int replications; + + if (tag.contains("r")) { + replications = (tag.getInt("r") + 1) % 4; + } else { + replications = 0; + } + + tag.putInt("r", replications); + + playerIn.sendMessage(new StringTextComponent((replications + 1) + "³ Replications")); + } + + return super.onItemRightClick(worldIn, playerIn, handIn); + } + @Override public ActionResultType onItemUseFirst(ItemStack stack, ItemUseContext context) { if (context.getWorld().isRemote()) { - return ActionResultType.PASS; + // Needed, otherwise client will trigger onItemRightClick also on server... + return ActionResultType.SUCCESS; } PlayerEntity player = context.getPlayer(); @@ -70,13 +93,15 @@ public class ReplicatorCardItem extends AEBaseItem { if (player.isCrouching()) { if (world.getTileEntity(pos) instanceof IGridHost) { - final CompoundNBT tag = new CompoundNBT(); + final CompoundNBT tag = player.getHeldItem(hand).getOrCreateTag(); tag.putInt("x", x); tag.putInt("y", y); tag.putInt("z", z); tag.putInt("side", side.ordinal()); tag.putInt("dimid", world.getDimension().getType().getId()); - player.getHeldItem(hand).setTag(tag); + tag.putInt("r", 0); + + this.outputMsg(player, "Set replicator source"); } else { this.outputMsg(player, "This is not a Grid Tile."); } @@ -89,56 +114,81 @@ public class ReplicatorCardItem extends AEBaseItem { final int src_side = ish.getInt("side"); final int dimid = ish.getInt("dimid"); final World src_w = world.getServer().getWorld(DimensionType.getById(dimid)); + final int replications = ish.getInt("r") + 1; final TileEntity te = src_w.getTileEntity(new BlockPos(src_x, src_y, src_z)); + if (te instanceof IGridHost) { final IGridHost gh = (IGridHost) te; final Direction sideOff = Direction.values()[src_side]; final Direction currentSideOff = side; final IGridNode n = gh.getGridNode(AEPartLocation.fromFacing(sideOff)); + if (n != null) { final IGrid g = n.getGrid(); + if (g != null) { final ISpatialCache sc = g.getCache(ISpatialCache.class); + if (sc.isValidRegion()) { final DimensionalCoord min = sc.getMin(); final DimensionalCoord max = sc.getMax(); - x += currentSideOff.getXOffset(); - y += currentSideOff.getYOffset(); - z += currentSideOff.getZOffset(); + // TODO: Why??? Places it one block up each time... + // x += currentSideOff.getXOffset(); + // y += currentSideOff.getYOffset(); + // z += currentSideOff.getZOffset(); + + final int sc_size_x = max.x - min.x; + final int sc_size_y = max.y - min.y; + final int sc_size_z = max.z - min.z; final int min_x = min.x; final int min_y = min.y; final int min_z = min.z; - final int rel_x = min.x - src_x + x; - final int rel_y = min.y - src_y + y; - final int rel_z = min.z - src_z + z; + // Invert to maintain correct sign for west/east + final int x_rot = (int) -Math.signum(MathHelper.wrapDegrees(player.rotationYaw)); + // Rotate by 90 degree, so north/south are negative/positive + final int z_rot = (int) Math.signum(MathHelper.wrapDegrees(player.rotationYaw + 90)); - final int scale_x = max.x - min.x; - final int scale_y = max.y - min.y; - final int scale_z = max.z - min.z; + // Loops for replication in each direction + for (int r_x = 0; r_x < replications; r_x++) { + for (int r_y = 0; r_y < replications; r_y++) { + for (int r_z = 0; r_z < replications; r_z++) { - for (int i = 1; i < scale_x; i++) { - for (int j = 1; j < scale_y; j++) { - for (int k = 1; k < scale_z; k++) { - final BlockPos p = new BlockPos(min_x + i, min_y + j, min_z + k); - final BlockPos d = new BlockPos(i + rel_x, j + rel_y, k + rel_z); - final BlockState state = src_w.getBlockState(p); - final Block blk = state.getBlock(); - final BlockState prev = world.getBlockState(d); + // Offset x/z by the rotation index. + // For sake of simplicity always grow upwards. + final int rel_x = min.x - src_x + x + (r_x * sc_size_x * x_rot); + final int rel_y = min.y - src_y + y + (r_y * sc_size_y); + final int rel_z = min.z - src_z + z + (r_z * sc_size_z * z_rot); - world.setBlockState(d, state); - if (blk != null && blk.hasTileEntity(state)) { - final TileEntity ote = src_w.getTileEntity(p); - final TileEntity nte = blk.createTileEntity(state, world); - final CompoundNBT data = new CompoundNBT(); - ote.write(data); - nte.read(data.copy()); - world.setTileEntity(d, nte); + // Copy a single SC instance completely + for (int i = 1; i < sc_size_x; i++) { + for (int j = 1; j < sc_size_y; j++) { + for (int k = 1; k < sc_size_z; k++) { + final BlockPos p = new BlockPos(min_x + i, min_y + j, + min_z + k); + final BlockPos d = new BlockPos(i + rel_x, j + rel_y, + k + rel_z); + + final BlockState state = src_w.getBlockState(p); + final Block blk = state.getBlock(); + final BlockState prev = world.getBlockState(d); + + world.setBlockState(d, state); + if (blk != null && blk.hasTileEntity(state)) { + final TileEntity ote = src_w.getTileEntity(p); + final TileEntity nte = blk.createTileEntity(state, world); + final CompoundNBT data = new CompoundNBT(); + ote.write(data); + nte.read(data.copy()); + world.setTileEntity(d, nte); + } + world.notifyBlockUpdate(d, prev, state, 3); + } + } } - world.notifyBlockUpdate(d, prev, state, 3); } } }