package com.matt.forgehax.mods; import static com.matt.forgehax.Helper.getLocalPlayer; import static com.matt.forgehax.Helper.getPlayerController; import static com.matt.forgehax.Helper.getWorld; import com.matt.forgehax.mods.managers.PositionRotationManager; import com.matt.forgehax.mods.managers.PositionRotationManager.RotationState; import com.matt.forgehax.mods.services.TickRateService; import com.matt.forgehax.util.Utils; import com.matt.forgehax.util.command.Setting; import com.matt.forgehax.util.common.PriorityEnum; import com.matt.forgehax.util.entity.EntityUtils; import com.matt.forgehax.util.key.Bindings; import com.matt.forgehax.util.math.Angle; import com.matt.forgehax.util.math.AngleHelper; import com.matt.forgehax.util.mod.Category; import com.matt.forgehax.util.mod.ToggleMod; import com.matt.forgehax.util.mod.loader.RegisterMod; import com.matt.forgehax.util.projectile.Projectile; import java.util.Comparator; import java.util.Optional; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.util.EnumHand; import net.minecraft.util.math.Vec3d; @RegisterMod public class Aimbot extends ToggleMod implements PositionRotationManager.MovementUpdateListener { private static Entity target = null; public static void setTarget(Entity target) { Aimbot.target = target; } public static Entity getTarget() { return target; } enum Selector { CROSSHAIR, DISTANCE, } private final Setting<Boolean> silent = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("silent") .description("Wont look at target when aiming") .defaultTo(true) .build(); private final Setting<Boolean> auto_attack = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("auto-attack") .description("Automatically attack when target found") .defaultTo(true) .build(); private final Setting<Boolean> hold_target = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("hold-target") .description("Keep first caught target until it becomes no longer valid") .defaultTo(false) .build(); private final Setting<Boolean> vis_check = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("trace") .description("Check if the target is visible before acquiring") .defaultTo(false) .build(); private final Setting<Boolean> target_players = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("target-players") .description("Target players") .defaultTo(true) .build(); private final Setting<Boolean> target_mobs_hostile = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("target-hostile-mobs") .description("Target hostile mobs") .defaultTo(true) .build(); private final Setting<Boolean> target_mobs_friendly = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("target-friendly-mobs") .description("Target friendly mobs") .defaultTo(false) .build(); private final Setting<Boolean> lag_compensation = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("lag-compensation") .description("Compensate for server lag") .defaultTo(true) .build(); private final Setting<Integer> fov = getCommandStub() .builders() .<Integer>newSettingBuilder() .name("fov") .description("Aimbot field of view") .defaultTo(180) .min(0) .max(180) .build(); private final Setting<Double> range = getCommandStub() .builders() .<Double>newSettingBuilder() .name("range") .description("Aimbot range") .defaultTo(4.5D) .build(); private final Setting<Float> cooldown_percent = getCommandStub() .builders() .<Float>newSettingBuilder() .name("cooldown_percent") .description("Minimum cooldown percent for next strike") .defaultTo(100F) .min(0F) .build(); private final Setting<Boolean> projectile_aimbot = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("proj-aimbot") .description("Projectile aimbot") .defaultTo(true) .build(); private final Setting<Boolean> projectile_auto_attack = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("proj-auto-attack") .description("Automatically attack when target found for projectile weapons") .defaultTo(true) .build(); private final Setting<Boolean> projectile_trace_check = getCommandStub() .builders() .<Boolean>newSettingBuilder() .name("projectile-trace") .description("Check the trace of each target if holding a weapon that fires a projectile") .defaultTo(true) .build(); private final Setting<Double> projectile_range = getCommandStub() .builders() .<Double>newSettingBuilder() .name("projectile-range") .description("Projectile aimbot range") .defaultTo(100D) .build(); private final Setting<Selector> selector = getCommandStub() .builders() .<Selector>newSettingEnumBuilder() .name("selector") .description("The method used to select a target from a group") .defaultTo(Selector.CROSSHAIR) .build(); public Aimbot() { super(Category.COMBAT, "Aimbot", false, "Automatically attack entities and players"); } private double getLagComp() { if (lag_compensation.get()) { return -(20.D - TickRateService.getTickData().getPoint().getAverage()); } else { return 0.D; } } private boolean canAttack(EntityPlayer localPlayer, Entity target) { final float cdRatio = cooldown_percent.get() / 100F; final float cdOffset = cdRatio <= 1F ? 0F : -(localPlayer.getCooldownPeriod() * (cdRatio - 1F)); return localPlayer.getCooledAttackStrength((float) getLagComp() + cdOffset) >= (Math.min(1F, cdRatio)) && (auto_attack.get() || Bindings.attack.getBinding().isKeyDown()); // need to work on this } private Projectile getHeldProjectile() { return Projectile.getProjectileByItemStack(getLocalPlayer().getHeldItem(EnumHand.MAIN_HAND)); } private boolean isHoldingProjectileItem() { return !getHeldProjectile().isNull(); } private boolean isProjectileAimbotActivated() { return projectile_aimbot.get() && isHoldingProjectileItem(); } private boolean isVisible(Entity target) { if (isProjectileAimbotActivated() && projectile_trace_check.get()) { return getHeldProjectile().canHitEntity(EntityUtils.getEyePos(getLocalPlayer()), target); } else { return !vis_check.get() || getLocalPlayer().canEntityBeSeen(target); } } private Vec3d getAttackPosition(Entity entity) { return EntityUtils.getInterpolatedPos(entity, 1).addVector(0, entity.getEyeHeight() / 2, 0); } /** * Check if the entity is a valid target to acquire */ private boolean filterTarget(Vec3d pos, Vec3d viewNormal, Angle angles, Entity entity) { final Vec3d tpos = getAttackPosition(entity); return Optional.of(entity) .filter(EntityUtils::isLiving) .filter(EntityUtils::isAlive) .filter(EntityUtils::isValidEntity) .filter(ent -> !ent.equals(getLocalPlayer())) .filter(this::isFiltered) .filter(ent -> isInRange(tpos, pos)) .filter(ent -> isInFov(angles, tpos.subtract(pos))) .filter(this::isVisible) .isPresent(); } private boolean isFiltered(Entity entity) { switch (EntityUtils.getRelationship(entity)) { case PLAYER: return target_players.get(); case FRIENDLY: case NEUTRAL: return target_mobs_friendly.get(); case HOSTILE: return target_mobs_hostile.get(); case INVALID: default: return false; } } private boolean isInRange(Vec3d from, Vec3d to) { double dist = isProjectileAimbotActivated() ? projectile_range.get() : range.get(); return dist <= 0 || from.distanceTo(to) <= dist; } private boolean isInFov(Angle angle, Vec3d pos) { double fov = this.fov.get(); if (fov >= 180) { return true; } else { Angle look = AngleHelper.getAngleFacingInDegrees(pos); Angle diff = angle.sub(look.getPitch(), look.getYaw()).normalize(); return Math.abs(diff.getPitch()) <= fov && Math.abs(diff.getYaw()) <= fov; } } private double selecting( final Vec3d pos, final Vec3d viewNormal, final Angle angles, final Entity entity) { switch (selector.get()) { case DISTANCE: return getAttackPosition(entity).subtract(pos).lengthSquared(); case CROSSHAIR: default: return getAttackPosition(entity) .subtract(pos) .normalize() .subtract(viewNormal) .lengthSquared(); } } private Entity findTarget(final Vec3d pos, final Vec3d viewNormal, final Angle angles) { return getWorld() .loadedEntityList .stream() .filter(entity -> filterTarget(pos, viewNormal, angles, entity)) .min(Comparator.comparingDouble(entity -> selecting(pos, viewNormal, angles, entity))) .orElse(null); } @Override protected void onEnabled() { PositionRotationManager.getManager().register(this, PriorityEnum.HIGHEST); } @Override public void onDisabled() { PositionRotationManager.getManager().unregister(this); } @Override public void onLocalPlayerMovementUpdate(RotationState.Local state) { Vec3d pos = EntityUtils.getEyePos(getLocalPlayer()); Vec3d look = getLocalPlayer().getLookVec(); Angle angles = AngleHelper.getAngleFacingInDegrees(look); Entity t = getTarget(); if (!hold_target.get() || t == null || !filterTarget(pos, look.normalize(), angles, getTarget())) { setTarget(t = findTarget(pos, look.normalize(), angles)); } if (t == null) { return; } final Entity tar = t; Projectile projectile = getHeldProjectile(); if (projectile.isNull() || !projectile_aimbot.get()) { // melee aimbot Angle va = Utils.getLookAtAngles(t).normalize(); state.setViewAngles(va, silent.get()); if (canAttack(getLocalPlayer(), tar)) { state.invokeLater( rs -> { getPlayerController().attackEntity(getLocalPlayer(), tar); getLocalPlayer().swingArm(EnumHand.MAIN_HAND); }); } } } }