seppuku/src/main/java/me/rigamortis/seppuku/impl/module/player/InteractModule.java

104 lines
4.6 KiB
Java

package me.rigamortis.seppuku.impl.module.player;
import me.rigamortis.seppuku.api.event.EventStageable;
import me.rigamortis.seppuku.api.event.network.EventSendPacket;
import me.rigamortis.seppuku.api.module.Module;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
import net.minecraft.network.play.client.CPacketUseEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import team.stiff.pomelo.impl.annotated.handler.annotation.Listener;
/**
* Author Seth
* 4/22/2019 @ 1:02 PM.
*/
public final class InteractModule extends Module {
private boolean clicked;
public InteractModule() {
super("Interact", new String[]{"GhostHand"}, "Allows you to access entities and blocks through walls", "NONE", -1, ModuleType.PLAYER);
}
@Listener
public void sendPacket(EventSendPacket event) {
if (event.getStage() == EventStageable.EventStage.PRE) {
if (event.getPacket() instanceof CPacketPlayerTryUseItemOnBlock) {
if (this.clicked) {
this.clicked = false;
return;
}
final CPacketPlayerTryUseItemOnBlock packet = (CPacketPlayerTryUseItemOnBlock) event.getPacket();
final Minecraft mc = Minecraft.getMinecraft();
if (mc.currentScreen == null) {
final Block block = mc.world.getBlockState(packet.getPos()).getBlock();
if (block.onBlockActivated(mc.world, packet.getPos(), mc.world.getBlockState(packet.getPos()), mc.player, packet.getHand(), packet.getDirection(), packet.getFacingX(), packet.getFacingY(), packet.getFacingZ())) {
return;
}
final BlockPos usable = findUsableBlock(packet.getHand(), packet.getDirection(), packet.getFacingX(), packet.getFacingY(), packet.getFacingZ());
if (usable != null) {
mc.player.swingArm(packet.getHand());
mc.player.connection.sendPacket(new CPacketPlayerTryUseItemOnBlock(usable, packet.getDirection(), packet.getHand(), packet.getFacingX(), packet.getFacingY(), packet.getFacingZ()));
this.clicked = true;
} else {
final Entity usableEntity = findUsableEntity(packet.getHand());
if (usableEntity != null) {
mc.player.connection.sendPacket(new CPacketUseEntity(usableEntity, packet.getHand()));
this.clicked = true;
}
}
}
}
}
}
private Entity findUsableEntity(EnumHand hand) {
final Minecraft mc = Minecraft.getMinecraft();
Entity entity = null;
for (int i = 0; i <= mc.playerController.getBlockReachDistance(); i++) {
final AxisAlignedBB bb = this.traceToBlock(i, mc.getRenderPartialTicks());
float maxDist = mc.playerController.getBlockReachDistance();
for (Entity e : mc.world.getEntitiesWithinAABBExcludingEntity(mc.player, bb)) {
float currentDist = mc.player.getDistance(e);
if (currentDist <= maxDist) {
entity = e;
maxDist = currentDist;
}
}
}
return entity;
}
private BlockPos findUsableBlock(EnumHand hand, EnumFacing dir, float x, float y, float z) {
final Minecraft mc = Minecraft.getMinecraft();
for (int i = 0; i <= mc.playerController.getBlockReachDistance(); i++) {
final AxisAlignedBB bb = this.traceToBlock(i, mc.getRenderPartialTicks());
final BlockPos pos = new BlockPos(bb.minX, bb.minY, bb.minZ);
final Block block = mc.world.getBlockState(pos).getBlock();
if (block.onBlockActivated(mc.world, pos, mc.world.getBlockState(pos), mc.player, hand, dir, x, y, z)) {
return new BlockPos(pos);
}
}
return null;
}
private AxisAlignedBB traceToBlock(double dist, float partialTicks) {
final Vec3d pos = Minecraft.getMinecraft().player.getPositionEyes(partialTicks);
final Vec3d angles = Minecraft.getMinecraft().player.getLook(partialTicks);
final Vec3d end = pos.add(angles.x * dist, angles.y * dist, angles.z * dist);
return new AxisAlignedBB(end.x, end.y, end.z, end.x + 1, end.y + 1, end.z + 1);
}
}