package ru.dedinside.modules.impl.combat;
import net.minecraft.block.BlockAir;
import net.minecraft.block.BlockLiquid;
import net.minecraft.block.material.Material;
import net.minecraft.client.entity.EntityOtherPlayerMP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.monster.EntityGolem;
import net.minecraft.entity.monster.EntityMob;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntitySquid;
import net.minecraft.entity.passive.EntityVillager;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.item.ItemShield;
import net.minecraft.network.play.client.CPacketEntityAction;
import net.minecraft.network.play.client.CPacketHeldItemChange;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import org.lwjgl.util.vector.Vector2f;
import ru.dedinside.Expensive;
import ru.dedinside.event.EventTarget;
import ru.dedinside.event.events.impl.EventInteract;
import ru.dedinside.event.events.impl.EventMotion;
import ru.dedinside.event.events.impl.EventUpdate;
import ru.dedinside.modules.Module;
import ru.dedinside.modules.ModuleAnnotation;
import ru.dedinside.modules.Type;
import ru.dedinside.ui.dropui.setting.imp.BooleanSetting;
import ru.dedinside.ui.dropui.setting.imp.ModeSetting;
import ru.dedinside.ui.dropui.setting.imp.MultiBoxSetting;
import ru.dedinside.ui.dropui.setting.imp.SliderSetting;
import ru.dedinside.util.GCDFixUtility;
import ru.dedinside.util.math.AdvancedCast;
import ru.dedinside.util.math.RotationUtility;
import ru.dedinside.util.movement.MoveUtility;
import ru.dedinside.util.world.InventoryUtility;
import ru.dedinside.util.world.RayCastUtility;
import java.util.ArrayList;
@ModuleAnnotation(name = "Aura", desc = "Аттакует противников", type = Type.Combat)
public class AuraModule extends Module {
public static EntityLivingBase targetEntity;
public boolean thisContextRotatedBefore;
public float prevAdditionYaw;
public static Vector2f rotation = new Vector2f();
float minCPS = 0;
public ModeSetting rotationModeSetting = new ModeSetting("Rotation Mode", "Matrix", "Matrix", "Sunrise");
public SliderSetting attackDistanceSetting = new SliderSetting("Distance", 3.3f, .0f, 6.0f, 0.01f);
public SliderSetting rotateDistanceSetting = new SliderSetting("Rotate Distance", 1.5f, .0f, 3.0f, 0.01f);
public MultiBoxSetting targetSelectionSetting = new MultiBoxSetting("Targets Selection", new String[]{"Players", "Mobs", "Animals", "Villagers"});
public BooleanSetting rayTraceSetting = new BooleanSetting("RayTrace", false);
public BooleanSetting resolverSetting = new BooleanSetting("Resolver", false);
public BooleanSetting onlyCriticalSetting = new BooleanSetting("Only Critical", true);
public BooleanSetting waterCriticalSetting = new BooleanSetting("Water Critical", true, () -> onlyCriticalSetting.get());
public BooleanSetting shieldBreakerSetting = new BooleanSetting("Shield Breaker", true);
private int changeSlotCounter;
public AuraModule() {
add(rotationModeSetting, attackDistanceSetting, rotateDistanceSetting, targetSelectionSetting, rayTraceSetting, resolverSetting, onlyCriticalSetting,
waterCriticalSetting, shieldBreakerSetting);
}
@EventTarget
public void onInteractEntity(EventInteract e) {
if (targetEntity != null) {
e.cancel();
}
}
@EventTarget
public void onUpdateAura(EventUpdate eventUpdate) {
if (resolverSetting.get()) {
resolvePlayers();
}
onAura();
if (resolverSetting.get()) {
releaseResolver();
}
}
@EventTarget
public void onMotion(EventMotion eventMotion) {
if (targetEntity != null) {
mc.player.rotationYawHead = rotation.x;
mc.player.renderYawOffset = rotation.x;
eventMotion.setYaw(rotation.x);
eventMotion.setPitch(rotation.y);
}
}
public void onAura() {
if (minCPS > 0) {
minCPS--;
}
// valid check.
if (targetEntity != null) {
if (!isValidTarget(targetEntity)) {
targetEntity = null;
}
}
// finder target.
if (targetEntity == null) targetEntity = findTarget();
if (targetEntity == null) {
rotation.x = mc.player.rotationYaw;
rotation.y = mc.player.rotationPitch;
return;
}
this.thisContextRotatedBefore = false;
// attacking target.
attackMethod(targetEntity);
// rotation updating.
getVectorRotation(targetEntity, false);
}
// attacking method.
public void attackMethod(Entity entity) {
if (whenFalling() && (minCPS == 0)) {
if (getHitBox(entity, attackDistanceSetting.getFloatValue()) == null && rayTraceSetting.get()) {
return;
}
mc.player.connection.sendPacket(new CPacketEntityAction(mc.player, CPacketEntityAction.Action.STOP_SPRINTING));
getVectorRotation(entity, true);
if (AdvancedCast.instance.getMouseOver(entity, rotation.x, rotation.y, attackDistanceSetting.getDoubleValue(), ignoreWalls()) == entity) {
if (mc.player.isActiveItemStackBlocking()) mc.playerController.onStoppedUsingItem(mc.player);
minCPS = 10;
mc.playerController.attackEntity(mc.player, targetEntity);
mc.player.swingArm(EnumHand.MAIN_HAND);
mc.player.resetCooldown();
breakShieldMethod((EntityPlayer) entity);
}
}
}
public void breakShieldMethod(EntityPlayer entity) {
if (InventoryUtility.doesHotbarHaveAxe() && shieldBreakerSetting.get()) {
int item = InventoryUtility.getAxe();
if (entity != null && entity.getActiveItemStack().getItem() instanceof ItemShield) {
mc.player.connection.sendPacket(new CPacketHeldItemChange(item));
mc.playerController.attackEntity(mc.player, entity);
mc.player.swingArm(EnumHand.MAIN_HAND);
mc.player.resetCooldown();
mc.player.connection.sendPacket(new CPacketHeldItemChange(mc.player.inventory.currentItem));
}
}
}
//method for rotation to target
public void getVectorRotation(Entity entity, boolean attackContext) {
this.thisContextRotatedBefore = true;
Vec3d vec = getHitBox(entity, rotateDistanceSetting.getFloatValue() + attackDistanceSetting.getFloatValue());
if (vec == null) {
vec = entity.getPositionEyes(1);
}
float sensitivity = 1.0001f;
double x, y, z;
x = vec.x - mc.player.posX;
y = vec.y - (mc.player.posY + mc.player.getEyeHeight());
z = vec.z - mc.player.posZ;
double dst = Math.sqrt(Math.pow(x, 2) + Math.pow(z, 2));
float yawToTarget = (float) MathHelper.wrapDegrees(Math.toDegrees(Math.atan2(z, x)) - 90);
float pitchToTarget = (float) (-Math.toDegrees(Math.atan2(y, dst)));
float yawDelta = MathHelper.wrapDegrees(yawToTarget - rotation.x) / sensitivity;
float pitchDelta = (pitchToTarget - rotation.y) / sensitivity;
if (yawDelta > 180) yawDelta = yawDelta - 180;
if (Math.abs(yawDelta) < 180.0f) {
float additionYaw = Math.min(Math.max(Math.abs(yawDelta), 1), 40);
float additionPitch = Math.max(attackContext ? Math.abs(pitchDelta) : 1, rotationModeSetting.is("Sunrise") ? 1 : 3);
if (Math.abs(additionYaw - this.prevAdditionYaw) <= 3.0f) {
additionYaw = GCDFixUtility.getFixedRotation(this.prevAdditionYaw + 3.1f);
}
float yaw = rotation.x + (yawDelta > 0 ? additionYaw : -additionYaw) * sensitivity;
float pitch = rotation.y + (pitchDelta > 0 ? additionPitch : -additionPitch) * sensitivity;
pitch = MathHelper.clamp(pitch, -90, 90);
rotation.x = yaw;
rotation.y = pitch;
prevAdditionYaw = additionYaw;
}
}
public boolean ignoreWalls() {
BlockPos pos = new BlockPos(mc.player.lastReportedPosX, mc.player.lastReportedPosY, mc.player.lastReportedPosZ);
return mc.world.getBlockState(pos).getMaterial() == Material.AIR;
}
public boolean whenFalling() {
boolean critWater = waterCriticalSetting.get() &&
mc.world.getBlockState(new BlockPos(mc.player.posX, mc.player.posY, mc.player.posZ)).getBlock()
instanceof BlockLiquid && mc.world.getBlockState(new BlockPos(mc.player.posX, mc.player.posY + 1,
mc.player.posZ)).getBlock() instanceof BlockAir;
boolean reason = mc.player.isPotionActive(MobEffects.BLINDNESS) || mc.player.isOnLadder()
|| mc.player.isInWater() && !critWater || mc.player.isInWeb || mc.player.capabilities.isFlying;
if (mc.player.getCooledAttackStrength(1.5f) < 0.92f) {
return false;
}
if (onlyCriticalSetting.state && !reason) {
if (MoveUtility.isBlockAboveHead() && mc.player.onGround && mc.player.fallDistance > 0) {
return true;
}
return !mc.player.onGround && mc.player.fallDistance != Math.ceil(mc.player.fallDistance);
}
return true;
}
public EntityLivingBase findTarget() {
ArrayList<EntityLivingBase> entity = new ArrayList<>();
for (Entity player : mc.world.loadedEntityList) {
if (!(player instanceof EntityLivingBase)) continue;
if (isValidTarget((EntityLivingBase) player)) {
entity.add((EntityLivingBase) player);
continue;
}
entity.remove(player);
}
// sorting to distance
entity.sort((e1, e2) -> {
int dst1 = (int) (mc.player.getDistance(e1) * 1000);
int dst2 = (int) (mc.player.getDistance(e2) * 1000);
return dst1 - dst2;
});
return entity.isEmpty() ? null : entity.get(0);
}
public boolean isValidTarget(EntityLivingBase e) {
if (e == this.mc.player)
return false;
if (e.isDead)
return false;
if (e.getHealth() <= 0)
return false;
if (e instanceof EntityArmorStand)
return false;
if (e instanceof EntityPlayer && !targetSelectionSetting.get(0))
return false;
if (Expensive.getInstance().friendManager.isFriend(e.getName()))
return false;
if (e instanceof EntityMob && !targetSelectionSetting.get(1))
return false;
if ((e instanceof EntityAnimal || e instanceof EntityGolem || e instanceof EntitySquid || e instanceof EntityVillager) && !targetSelectionSetting.get(2))
return false;
if (e instanceof EntityVillager && targetSelectionSetting.get(3))
return false;
if (!ignoreWalls()) {
if (getHitBox(e, attackDistanceSetting.getDoubleValue() + rotateDistanceSetting.getDoubleValue()) == null) {
return false;
}
} else
return !(e.getDistance(mc.player) > attackDistanceSetting.getDoubleValue() + rotateDistanceSetting.getDoubleValue());
return true;
}
public void resolvePlayers() {
for (EntityPlayer player : mc.world.playerEntities) {
if (player instanceof EntityOtherPlayerMP) {
((EntityOtherPlayerMP) player).resolve();
}
}
}
public void releaseResolver() {
for (EntityPlayer player : mc.world.playerEntities) {
if (player instanceof EntityOtherPlayerMP) {
((EntityOtherPlayerMP) player).releaseResolver();
}
}
}
public Vec3d getHitBox(Entity entity, double rotateDistance) {
Vec3d vec = entity.getPositionVector().add(new Vec3d(0, MathHelper.clamp(entity.getEyeHeight() * (mc.player.getDistance(entity) / (attackDistanceSetting.getFloatValue() + rotateDistanceSetting.getFloatValue()) + entity.width), 0.2, mc.player.getEyeHeight()), 0));
ArrayList<Vec3d> points = new ArrayList<>();
points.add(vec);
points.removeIf(point -> !isHitBoxVisible(entity, point, rotateDistance));
if (points.isEmpty()) {
return null;
}
points.sort((d1, d2) -> {
Vector2f r1 = RotationUtility.getDeltaForCoord(rotation, d1);
Vector2f r2 = RotationUtility.getDeltaForCoord(rotation, d2);
float y1 = Math.abs(r1.y);
float y2 = Math.abs(r2.y);
return (int) ((y1 - y2) * 1000);
});
return points.get(0);
}
public boolean isHitBoxVisible(Entity target, Vec3d vector, double dst) {
return RayCastUtility.getPointedEntity(RotationUtility.getRotationForCoord(vector), dst, 1, !ignoreWalls(),
target) == target;
}
@Override
public void onDisable() {
targetEntity = null;
rotation.x = mc.player.rotationYaw;
rotation.y = mc.player.rotationPitch;
super.onDisable();
}
}