package me.rigamortis.seppuku.impl.module.movement; import me.rigamortis.seppuku.api.event.EventStageable; import me.rigamortis.seppuku.api.event.player.EventUpdateWalkingPlayer; import me.rigamortis.seppuku.api.module.Module; import me.rigamortis.seppuku.api.util.MathUtil; import me.rigamortis.seppuku.api.value.Value; import net.minecraft.block.Block; import net.minecraft.block.BlockLiquid; import net.minecraft.block.state.IBlockState; import net.minecraft.client.Minecraft; import net.minecraft.init.Blocks; import net.minecraft.init.Items; import net.minecraft.inventory.ClickType; import net.minecraft.item.Item; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.network.play.client.CPacketEntityAction; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import team.stiff.pomelo.impl.annotated.handler.annotation.Listener; import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; /** * Author Seth * 6/4/2019 @ 10:18 PM. */ public final class ScaffoldModule extends Module { public final Value<Boolean> refill = new Value<Boolean>("Refill", new String[]{"ref"}, "If the held item is empty or not a block, fill the slot with a block from the inventory when the scaffold is triggered to place.", true); public final Value<Boolean> destroy = new Value<Boolean>("Destroy", new String[]{"Dest"}, "When enabled, after placing the block, forces the player to swing/destroy at the same position.", false); private int[] blackList = new int[]{145, 130, 12, 252, 54, 146, 122, 13, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 50}; private List<BlockPos> blocks = new CopyOnWriteArrayList<BlockPos>(); public ScaffoldModule() { super("Scaffold", new String[]{"Scaff"}, "Automatically places blocks where you are walking.", "NONE", -1, ModuleType.MOVEMENT); } @Override public String getMetaData() { return "" + this.getBlockCount(); } @Override public void onToggle() { super.onToggle(); this.blocks.clear(); } @Listener public void onWalkingUpdate(EventUpdateWalkingPlayer event) { if (event.getStage() == EventStageable.EventStage.PRE) { final Minecraft mc = Minecraft.getMinecraft(); if (mc.player.noClip) { return; } if (this.destroy.getValue()) { double maxDist = 4.5f; BlockPos closest = null; for (BlockPos pos : this.blocks) { if (mc.world.getBlockState(pos).getBlock() != Blocks.AIR && this.canBreak(pos) && mc.player.getDistance(pos.getX(), pos.getY(), pos.getZ()) <= 4.5f && mc.player.getDistance(pos.getX(), pos.getY(), pos.getZ()) >= 2 && pos != mc.player.getPosition()) { final double dist = mc.player.getDistance(pos.getX(), pos.getY(), pos.getZ()); if (dist <= maxDist) { maxDist = dist; closest = pos; } } } if (closest != null) { mc.playerController.onPlayerDamageBlock(closest, EnumFacing.DOWN); mc.player.swingArm(EnumHand.MAIN_HAND); } } if ((mc.player.movementInput.moveForward != 0 || mc.player.movementInput.moveStrafe != 0 || mc.player.movementInput.jump) && !mc.player.movementInput.sneak) { final double[] dir = MathUtil.directionSpeed(1); if (mc.player.getHeldItemMainhand().getItem() != Items.AIR && mc.player.getHeldItemMainhand().getItem() instanceof ItemBlock && canPlace(mc.player.getHeldItemMainhand())) { final Vec3d block = getFirstBlock(dir); if (block != null) { final BlockPos pos = new BlockPos(block.x, block.y, block.z); this.placeBlock(pos); if (this.destroy.getValue() && this.canBreak(pos)) { this.blocks.add(pos); } } } else { final Vec3d block = getFirstBlock(dir); if (this.refill.getValue() && block != null) { final int slot = this.findStackHotbar(); if (slot != -1) { mc.player.inventory.currentItem = slot; mc.playerController.updateController(); } else { final int invSlot = findStackInventory(); if (invSlot != -1) { final int empty = findEmptyhotbar(); mc.playerController.windowClick(mc.player.inventoryContainer.windowId, invSlot, empty == -1 ? mc.player.inventory.currentItem : empty, ClickType.SWAP, mc.player); mc.playerController.updateController(); mc.player.setVelocity(0, 0, 0); } } } } } } } private int getBlockCount() { int count = 0; for (int i = 0; i < 36; i++) { final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); if (canPlace(stack) && stack.getItem() instanceof ItemBlock) { count += stack.getCount(); } } return count; } private int findEmptyhotbar() { for (int i = 0; i < 9; i++) { final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); if (stack.getItem() == Items.AIR) { return i; } } return -1; } private int findStackInventory() { for (int i = 9; i < 36; i++) { final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); if (canPlace(stack) && stack.getItem() instanceof ItemBlock) { return i; } } return -1; } private int findStackHotbar() { for (int i = 0; i < 9; i++) { final ItemStack stack = Minecraft.getMinecraft().player.inventory.getStackInSlot(i); if (canPlace(stack) && stack.getItem() instanceof ItemBlock) { return i; } } return -1; } private void placeBlock(BlockPos pos) { final Minecraft mc = Minecraft.getMinecraft(); BlockPos[][] posit = {{pos.add(0, 0, 1), pos.add(0, 0, -1)}, {pos.add(0, 1, 0), pos.add(0, -1, 0)}, {pos.add(1, 0, 0),pos.add(-1, 0, 0)}}; EnumFacing[][] facing = {{EnumFacing.NORTH, EnumFacing.SOUTH}, {EnumFacing.DOWN, EnumFacing.UP}, {EnumFacing.WEST, EnumFacing.EAST}}; // Facing reversed as blocks are placed while facing in the opposite direction for (int i=0; i<6; i++) { final Block block = mc.world.getBlockState(posit[i/2][i%2]).getBlock(); final boolean activated = block.onBlockActivated(mc.world, pos, mc.world.getBlockState(pos), mc.player, EnumHand.MAIN_HAND, EnumFacing.UP, 0, 0, 0); if (block != null && block != Blocks.AIR && !(block instanceof BlockLiquid)) { if (activated) mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.START_SNEAKING)); if (mc.playerController.processRightClickBlock(mc.player, mc.world, posit[i/2][i%2], facing[i/2][i%2], new Vec3d(0d, 0d, 0d), EnumHand.MAIN_HAND) != EnumActionResult.FAIL) mc.player.swingArm(EnumHand.MAIN_HAND); if (activated) mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.STOP_SNEAKING)); } } } private boolean canPlace(ItemStack stack) { for (int id = 0; id < this.blackList.length; id++) { if (Item.getIdFromItem(stack.getItem()) == this.blackList[id]) { return false; } } return true; } private Vec3d getFirstBlock(double[] dir) { final Minecraft mc = Minecraft.getMinecraft(); Vec3d pos = new Vec3d(mc.player.posX, mc.player.posY - 1, mc.player.posZ); Vec3d dirpos = new Vec3d(mc.player.posX + dir[0], mc.player.posY - 1, mc.player.posZ + dir[1]); if (mc.world.getBlockState(new BlockPos(pos.x, pos.y, pos.z)).getBlock() == Blocks.AIR) return pos; if (mc.world.getBlockState(new BlockPos(dirpos.x, dirpos.y, dirpos.z)).getBlock() == Blocks.AIR) if (mc.world.getBlockState(new BlockPos(pos.x, dirpos.y, dirpos.z)).getBlock() == Blocks.AIR && mc.world.getBlockState(new BlockPos(dirpos.x, dirpos.y, pos.z)).getBlock() == Blocks.AIR) { return new Vec3d(dirpos.x, pos.y, pos.z); } else { return dirpos; } return null; } private boolean canBreak(BlockPos pos) { final IBlockState blockState = Minecraft.getMinecraft().world.getBlockState(pos); final Block block = blockState.getBlock(); return block.getBlockHardness(blockState, Minecraft.getMinecraft().world, pos) != -1 && !(block instanceof BlockLiquid); } private boolean blockExists(Vec3d pos) { final Block block = Minecraft.getMinecraft().world.getBlockState(new BlockPos(pos.x, pos.y, pos.z)).getBlock(); return block != Blocks.AIR; } }