package wtf.season.functions.impl.combat;
import com.google.common.eventbus.Subscribe;
import gi.pusta.events.EventUpdate;
import gi.pusta.functions.api.Category;
import gi.pusta.functions.api.Function;
import gi.pusta.functions.api.FunctionRegister;
import gi.pusta.functions.settings.impl.BooleanSetting;
import gi.pusta.functions.settings.impl.SliderSetting;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.monster.CreeperEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
@FunctionRegister(name = "CreeperFarm", type = Category.Combat)
public class CreeperFarm extends Function {
private final SliderSetting distanceSetting = new SliderSetting("Дистанция", 10.0f, 5.0f, 20.0f, 0.5f);
private final SliderSetting chaseSpeedSetting = new SliderSetting("Скорость погони", 1.0f, 0.5f, 2.0f, 0.1f);
private final BooleanSetting chaseModeSetting = new BooleanSetting("Режим погони", false);
private final BooleanSetting autoCollectSetting = new BooleanSetting("Авто-сбор", true);
private static final Minecraft mc = Minecraft.getInstance();
private CreeperEntity targetCreeper;
public CreeperFarm() {
addSettings(distanceSetting, chaseSpeedSetting, chaseModeSetting, autoCollectSetting);
}
@Subscribe
public void onUpdate(EventUpdate event) {
if (mc.world == null || mc.player == null) return;
targetCreeper = findClosestCreeper();
if (targetCreeper == null) return;
double distanceSq = mc.player.getDistanceSq(targetCreeper);
if (distanceSq > distanceSetting.get() * distanceSetting.get()) return;
if (chaseModeSetting.get()) {
chaseCreeper(targetCreeper);
} else {
pullCreeper(targetCreeper);
}
if (autoCollectSetting.get()) {
BlockPos belowPos = new BlockPos(targetCreeper.getPosX(), targetCreeper.getPosY() - 1, targetCreeper.getPosZ());
if (mc.world.isAirBlock(belowPos)) {
mc.world.setBlockState(belowPos, net.minecraft.block.Blocks.HOPPER.getDefaultState());
mc.world.setBlockState(belowPos.down(), net.minecraft.block.Blocks.CHEST.getDefaultState());
}
}
}
private CreeperEntity findClosestCreeper() {
CreeperEntity closestCreeper = null;
double closestDistanceSq = Double.MAX_VALUE;
for (Entity entity : mc.world.getAllEntities()) {
if (entity instanceof CreeperEntity) {
double distanceSq = mc.player.getDistanceSq(entity);
if (distanceSq < closestDistanceSq && distanceSq <= distanceSetting.get() * distanceSetting.get()) {
closestCreeper = (CreeperEntity) entity;
closestDistanceSq = distanceSq;
}
}
}
return closestCreeper;
}
private void chaseCreeper(CreeperEntity creeper) {
float[] rotations = calculateRotations(creeper);
mc.player.rotationYaw = smoothRotation(mc.player.rotationYaw, rotations[0], 0.5f);
mc.player.rotationPitch = smoothRotation(mc.player.rotationPitch, rotations[1], 0.5f);
double dx = creeper.getPosX() - mc.player.getPosX();
double dz = creeper.getPosZ() - mc.player.getPosZ();
double distance = Math.sqrt(dx * dx + dz * dz);
if (distance > 2.0) {
double speed = chaseSpeedSetting.get();
mc.player.setMotion(
dx / distance * speed,
mc.player.getMotion().y,
dz / distance * speed
);
}
}
private void pullCreeper(CreeperEntity creeper) {
double targetX = mc.player.getPosX();
double targetY = mc.player.getPosY() + 3.0;
double targetZ = mc.player.getPosZ();
double dx = targetX - creeper.getPosX();
double dy = targetY - creeper.getPosY();
double dz = targetZ - creeper.getPosZ();
float speed = 0.1f;
creeper.setMotion(
creeper.getMotion().x + dx * speed,
creeper.getMotion().y + dy * speed,
creeper.getMotion().z + dz * speed
);
}
private float[] calculateRotations(Entity entity) {
double x = entity.getPosX() - mc.player.getPosX();
double y = entity.getPosY() - mc.player.getPosY() + entity.getEyeHeight() - mc.player.getEyeHeight();
double z = entity.getPosZ() - mc.player.getPosZ();
double dist = Math.sqrt(x * x + z * z);
float yaw = (float) ((Math.atan2(z, x) * 180 / Math.PI) - 90);
float pitch = (float) (-(Math.atan2(y, dist) * 180 / Math.PI));
return new float[]{yaw, pitch};
}
private float smoothRotation(float current, float target, float factor) {
float delta = MathHelper.wrapDegrees(target - current);
return current + delta * factor;
}
}