From df318ca9711c31389c38699bbcf473d69feea97d Mon Sep 17 00:00:00 2001 From: wuritz Date: Sun, 29 Jun 2025 11:59:01 +0200 Subject: [PATCH 1/4] meg mielott elbasznam --- .../com/genyo/addon/hud/PvPNeccessaryHud.java | 2 - .../genyo/addon/mixin/PlayerUtilsMixin.java | 1 - .../com/genyo/addon/modules/CoopCrystal.java | 1595 +++++++++++++++++ .../com/genyo/addon/modules/GenyoAutoEZ.java | 67 +- .../com/genyo/addon/modules/GenyoKristaj.java | 1385 ++++++++++++++ src/main/resources/assets/genyo/icon.png | Bin 2137 -> 3351 bytes 6 files changed, 2994 insertions(+), 56 deletions(-) create mode 100644 src/main/java/com/genyo/addon/modules/CoopCrystal.java create mode 100644 src/main/java/com/genyo/addon/modules/GenyoKristaj.java diff --git a/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java b/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java index 3436596..89b5ee5 100644 --- a/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java +++ b/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java @@ -7,8 +7,6 @@ import meteordevelopment.meteorclient.systems.hud.HudElement; import meteordevelopment.meteorclient.systems.hud.HudElementInfo; import meteordevelopment.meteorclient.systems.hud.HudRenderer; -import meteordevelopment.meteorclient.utils.player.InvUtils; -import meteordevelopment.meteorclient.utils.render.color.Color; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; diff --git a/src/main/java/com/genyo/addon/mixin/PlayerUtilsMixin.java b/src/main/java/com/genyo/addon/mixin/PlayerUtilsMixin.java index f6220da..176915f 100644 --- a/src/main/java/com/genyo/addon/mixin/PlayerUtilsMixin.java +++ b/src/main/java/com/genyo/addon/mixin/PlayerUtilsMixin.java @@ -15,7 +15,6 @@ public class PlayerUtilsMixin { @Inject(at = @At("TAIL"), method = "getPlayerColor*", cancellable = true) private static void injectGetPlayerColor(PlayerEntity entity, Color defaultColor, CallbackInfoReturnable cir) { if (Enemies.get().isEnemy(entity)) { - //cir.setReturnValue(new Color(245, 133, 125, 255)); cir.setReturnValue(Enemies.get().getEnemyColor()); } } diff --git a/src/main/java/com/genyo/addon/modules/CoopCrystal.java b/src/main/java/com/genyo/addon/modules/CoopCrystal.java new file mode 100644 index 0000000..998c82f --- /dev/null +++ b/src/main/java/com/genyo/addon/modules/CoopCrystal.java @@ -0,0 +1,1595 @@ +package com.genyo.addon.modules; + +import com.genyo.addon.GenyoAddon; +import kassuk.addon.blackout.BlackOut; +import kassuk.addon.blackout.BlackOutModule; +import kassuk.addon.blackout.enums.RotationType; +import kassuk.addon.blackout.enums.SwingHand; +import kassuk.addon.blackout.enums.SwingState; +import kassuk.addon.blackout.enums.SwingType; +import kassuk.addon.blackout.managers.Managers; +import kassuk.addon.blackout.mixins.IInteractEntityC2SPacket; +import kassuk.addon.blackout.timers.TimerList; +import kassuk.addon.blackout.utils.BOInvUtils; +import kassuk.addon.blackout.utils.ExtrapolationUtils; +import kassuk.addon.blackout.utils.OLEPOSSUtils; +import kassuk.addon.blackout.utils.SettingUtils; +import kassuk.addon.blackout.utils.meteor.BODamageUtils; +import kassuk.addon.blackout.utils.meteor.BOEntityUtils; +import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; +import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.renderer.ShapeMode; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.Modules; +import meteordevelopment.meteorclient.utils.player.InvUtils; +import meteordevelopment.meteorclient.utils.render.color.Color; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import meteordevelopment.orbit.EventHandler; +import meteordevelopment.orbit.EventPriority; +import net.minecraft.block.AirBlock; +import net.minecraft.block.Blocks; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.decoration.EndCrystalEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; +import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; +import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket; +import net.minecraft.util.Hand; +import net.minecraft.util.math.*; + +import java.util.*; +import java.util.function.Predicate; + +public class CoopCrystal extends Module { + public CoopCrystal() { + super(GenyoAddon.GENYO, "Coop Crystal", "Tehát."); + } + + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgPlace = settings.createGroup("Place"); + private final SettingGroup sgExplode = settings.createGroup("Explode"); + private final SettingGroup sgSwitch = settings.createGroup("Switch"); + private final SettingGroup sgDamage = settings.createGroup("Damage"); + private final SettingGroup sgID = settings.createGroup("ID Predict"); + private final SettingGroup sgExtrapolation = settings.createGroup("Extrapolation"); + private final SettingGroup sgRender = settings.createGroup("Render"); + private final SettingGroup sgCompatibility = settings.createGroup("Compatibility"); + private final SettingGroup sgDebug = settings.createGroup("Debug"); + + //--------------------General--------------------// + private final Setting place = sgGeneral.add(new BoolSetting.Builder() + .name("Place") + .description("Places crystals.") + .defaultValue(true) + .build() + ); + private final Setting explode = sgGeneral.add(new BoolSetting.Builder() + .name("Explode") + .description("Explodes crystals.") + .defaultValue(true) + .build() + ); + private final Setting pauseEat = sgGeneral.add(new BoolSetting.Builder() + .name("Pause Eat") + .description("Pauses while eating.") + .defaultValue(false) + .build() + ); + private final Setting performance = sgGeneral.add(new BoolSetting.Builder() + .name("Performance Mode") + .description("Doesn't calculate placements as often.") + .defaultValue(false) + .build() + ); + private final Setting smartRot = sgGeneral.add(new BoolSetting.Builder() + .name("Smart Rotations") + .description("Looks at the top of placement block to make the ca faster.") + .defaultValue(true) + .build() + ); + private final Setting ignoreTerrain = sgGeneral.add(new BoolSetting.Builder() + .name("Ignore Terrain") + .description("Spams trough terrain to kill your enemy.") + .defaultValue(true) + .build() + ); + + //--------------------Place--------------------// + private final Setting instantPlace = sgPlace.add(new BoolSetting.Builder() + .name("Instant Place") + .description("Ignores delay after crystal has disappeared.") + .defaultValue(true) + .build() + ); + private final Setting speedLimit = sgPlace.add(new DoubleSetting.Builder() + .name("Speed Limit") + .description("Maximum amount of place packets every second. 0 = no limit.") + .defaultValue(0) + .min(0) + .sliderRange(0, 20) + .visible(instantPlace::get) + .build() + ); + private final Setting placeSpeed = sgPlace.add(new DoubleSetting.Builder() + .name("Place Speed") + .description("How many times should the module place per second.") + .defaultValue(10) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting placeDelayMode = sgPlace.add(new EnumSetting.Builder() + .name("Place Delay Mode") + .description("Should we count the delay in seconds or ticks.") + .defaultValue(DelayMode.Seconds) + .build() + ); + private final Setting placeDelay = sgPlace.add(new DoubleSetting.Builder() + .name("Place Delay") + .description("How many seconds after attacking a crystal should we place.") + .defaultValue(0) + .min(0) + .sliderRange(0, 1) + .visible(() -> placeDelayMode.get() == DelayMode.Seconds) + .build() + ); + private final Setting placeDelayTicks = sgPlace.add(new IntSetting.Builder() + .name("Place Delay Ticks") + .description("How many ticks should the crystal exist before attacking.") + .defaultValue(0) + .min(0) + .sliderRange(0, 20) + .visible(() -> placeDelayMode.get() == DelayMode.Ticks) + .build() + ); + private final Setting slowDamage = sgPlace.add(new DoubleSetting.Builder() + .name("Slow Damage") + .description("Switches to slow speed when the target would take under this amount of damage.") + .defaultValue(3) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting slowSpeed = sgPlace.add(new DoubleSetting.Builder() + .name("Slow Speed") + .description("How many times should the module place per second when damage is under slow damage.") + .defaultValue(2) + .min(0) + .sliderRange(0, 20) + .build() + ); + + //--------------------Explode--------------------// + private final Setting onlyOwn = sgExplode.add(new BoolSetting.Builder() + .name("Only Own") + .description("Only attacks own crystals.") + .defaultValue(false) + .build() + ); + private final Setting inhibit = sgExplode.add(new BoolSetting.Builder() + .name("Inhibit") + .description("Stops targeting attacked crystals.") + .defaultValue(false) + .build() + ); + private final Setting existedMode = sgExplode.add(new EnumSetting.Builder() + .name("Existed Mode") + .description("Should crystal existed times be counted in seconds or ticks.") + .defaultValue(DelayMode.Seconds) + .build() + ); + private final Setting existed = sgExplode.add(new DoubleSetting.Builder() + .name("Existed") + .description("How many seconds should the crystal exist before attacking.") + .defaultValue(0) + .min(0) + .sliderRange(0, 1) + .visible(() -> existedMode.get() == DelayMode.Seconds) + .build() + ); + private final Setting existedTicks = sgExplode.add(new IntSetting.Builder() + .name("Existed Ticks") + .description("How many ticks should the crystal exist before attacking.") + .defaultValue(0) + .min(0) + .sliderRange(0, 20) + .visible(() -> existedMode.get() == DelayMode.Ticks) + .build() + ); + private final Setting sequential = sgExplode.add(new EnumSetting.Builder() + .name("Sequential") + .description("Doesn't place and attack during the same tick.") + .defaultValue(SequentialMode.Disabled) + .build() + ); + private final Setting instantAttack = sgExplode.add(new BoolSetting.Builder() + .name("Instant Attack") + .description("Delay isn't calculated for first attack.") + .defaultValue(true) + .build() + ); + private final Setting expSpeedLimit = sgExplode.add(new DoubleSetting.Builder() + .name("Explode Speed Limit") + .description("How many times to hit any crystal each second. 0 = no limit") + .defaultValue(0) + .min(0) + .sliderRange(0, 20) + .visible(instantAttack::get) + .build() + ); + private final Setting expSpeed = sgExplode.add(new DoubleSetting.Builder() + .name("Explode Speed") + .description("How many times to hit crystal each second.") + .defaultValue(4) + .range(0.01, 20) + .sliderRange(0.01, 20) + .build() + ); + private final Setting setDead = sgExplode.add(new BoolSetting.Builder() + .name("Set Dead") + .description("Hides the crystal after hitting it. Not needed since the module already is smart enough.") + .defaultValue(false) + .build() + ); + private final Setting setDeadDelay = sgExplode.add(new DoubleSetting.Builder() + .name("Set Dead Delay") + .description("How long after hitting should the crystal disappear.") + .defaultValue(0.05) + .range(0, 1) + .sliderRange(0, 1) + .visible(setDead::get) + .build() + ); + + //--------------------Switch--------------------// + private final Setting switchMode = sgSwitch.add(new EnumSetting.Builder() + .name("Switch Mode") + .description("Mode for switching to crystal in main hand.") + .defaultValue(SwitchMode.Disabled) + .build() + ); + private final Setting switchPenalty = sgSwitch.add(new DoubleSetting.Builder() + .name("Switch Penalty") + .description("Time to wait after switching before hitting crystals.") + .defaultValue(0.25) + .min(0) + .sliderRange(0, 1) + .build() + ); + + //--------------------Damage--------------------// + private final Setting dmgCheckMode = sgDamage.add(new EnumSetting.Builder() + .name("Dmg Check Mode") + .description("How safe are the placements (normal is good).") + .defaultValue(DmgCheckMode.Normal) + .build() + ); + private final Setting minPlace = sgDamage.add(new DoubleSetting.Builder() + .name("Min Place") + .description("Minimum damage to place.") + .defaultValue(4) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting maxPlace = sgDamage.add(new DoubleSetting.Builder() + .name("Max Place") + .description("Max self damage for placing.") + .defaultValue(8) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting minPlaceRatio = sgDamage.add(new DoubleSetting.Builder() + .name("Min Place Ratio") + .description("Max self damage ratio for placing (enemy / self).") + .defaultValue(1.4) + .min(0) + .sliderRange(0, 5) + .build() + ); + private final Setting maxFriendPlace = sgDamage.add(new DoubleSetting.Builder() + .name("Max Friend Place") + .description("Max friend damage for placing.") + .defaultValue(8) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting minFriendPlaceRatio = sgDamage.add(new DoubleSetting.Builder() + .name("Min Friend Place Ratio") + .description("Max friend damage ratio for placing (enemy / friend).") + .defaultValue(2) + .min(0) + .sliderRange(0, 5) + .build() + ); + private final Setting expMode = sgDamage.add(new EnumSetting.Builder() + .name("Explode Damage Mode") + .description("Which things should be checked for exploding.") + .defaultValue(ExplodeMode.FullCheck) + .build() + ); + private final Setting minExplode = sgDamage.add(new DoubleSetting.Builder() + .name("Min Explode") + .description("Minimum enemy damage for exploding a crystal.") + .defaultValue(2.5) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting maxExp = sgDamage.add(new DoubleSetting.Builder() + .name("Max Explode") + .description("Max self damage for exploding a crystal.") + .defaultValue(9) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting minExpRatio = sgDamage.add(new DoubleSetting.Builder() + .name("Min Explode Ratio") + .description("Max self damage ratio for exploding a crystal (enemy / self).") + .defaultValue(1.1) + .min(0) + .sliderRange(0, 5) + .build() + ); + private final Setting maxFriendExp = sgDamage.add(new DoubleSetting.Builder() + .name("Max Friend Explode") + .description("Max friend damage for exploding a crystal.") + .defaultValue(12) + .min(0) + .sliderRange(0, 20) + .build() + ); + private final Setting minFriendExpRatio = sgDamage.add(new DoubleSetting.Builder() + .name("Min Friend Explode Ratio") + .description("Min friend damage ratio for exploding a crystal (enemy / friend).") + .defaultValue(2) + .min(0) + .sliderRange(0, 5) + .build() + ); + private final Setting forcePop = sgDamage.add(new DoubleSetting.Builder() + .name("Force Pop") + .description("Ignores damage checks if any enemy will be popped in x hits.") + .defaultValue(1) + .min(0) + .sliderRange(0, 10) + .build() + ); + private final Setting antiFriendPop = sgDamage.add(new DoubleSetting.Builder() + .name("Anti Friend Pop") + .description("Cancels any action if any friend will be popped in x hits.") + .defaultValue(1) + .min(0) + .sliderRange(0, 10) + .build() + ); + private final Setting antiSelfPop = sgDamage.add(new DoubleSetting.Builder() + .name("Anti Self Pop") + .description("Cancels any action if you will be popped in x hits.") + .defaultValue(1) + .min(0) + .sliderRange(0, 10) + .build() + ); + + //--------------------ID-Predict--------------------// + private final Setting idPredict = sgID.add(new BoolSetting.Builder() + .name("ID Predict") + .description("Hits the crystal before it spawns.") + .defaultValue(false) + .build() + ); + private final Setting idStartOffset = sgID.add(new IntSetting.Builder() + .name("Id Start Offset") + .description("How many id's ahead should we attack.") + .defaultValue(1) + .min(0) + .sliderMax(10) + .build() + ); + private final Setting idOffset = sgID.add(new IntSetting.Builder() + .name("Id Packet Offset") + .description("How many id's ahead should we attack between id packets.") + .defaultValue(1) + .min(1) + .sliderMax(10) + .build() + ); + private final Setting idPackets = sgID.add(new IntSetting.Builder() + .name("Id Packets") + .description("How many packets to send.") + .defaultValue(1) + .min(1) + .sliderMax(10) + .build() + ); + private final Setting idDelay = sgID.add(new DoubleSetting.Builder() + .name("ID Start Delay") + .description("Starts sending id predict packets after this many seconds.") + .defaultValue(0.05) + .min(0) + .sliderRange(0, 1) + .build() + ); + private final Setting idPacketDelay = sgID.add(new DoubleSetting.Builder() + .name("ID Packet Delay") + .description("Waits this many seconds between sending ID packets.") + .defaultValue(0.05) + .min(0) + .sliderRange(0, 1) + .build() + ); + + //--------------------Extrapolation--------------------// + private final Setting selfExt = sgExtrapolation.add(new IntSetting.Builder() + .name("Self Extrapolation") + .description("How many ticks of movement should be predicted for self damage checks.") + .defaultValue(0) + .range(0, 100) + .sliderMax(20) + .build() + ); + private final Setting extrapolation = sgExtrapolation.add(new IntSetting.Builder() + .name("Extrapolation") + .description("How many ticks of movement should be predicted for enemy damage checks.") + .defaultValue(0) + .range(0, 100) + .sliderMax(20) + .build() + ); + private final Setting rangeExtrapolation = sgExtrapolation.add(new IntSetting.Builder() + .name("Range Extrapolation") + .description("How many ticks of movement should be predicted for attack ranges before placing.") + .defaultValue(0) + .range(0, 100) + .sliderMax(20) + .build() + ); + private final Setting hitboxExtrapolation = sgExtrapolation.add(new IntSetting.Builder() + .name("Hitbox Extrapolation") + .description("How many ticks of movement should be predicted for hitboxes in placing checks.") + .defaultValue(0) + .range(0, 100) + .sliderMax(20) + .build() + ); + private final Setting extSmoothness = sgExtrapolation.add(new IntSetting.Builder() + .name("Extrapolation Smoothening") + .description("How many earlier ticks should be used in average calculation for extrapolation motion.") + .defaultValue(2) + .range(1, 20) + .sliderRange(1, 20) + .build() + ); + + //--------------------Render--------------------// + private final Setting placeSwing = sgRender.add(new BoolSetting.Builder() + .name("Place Swing") + .description("Renders swing animation when placing a crystal.") + .defaultValue(true) + .build() + ); + private final Setting placeHand = sgRender.add(new EnumSetting.Builder() + .name("Place Hand") + .description("Which hand should be swung.") + .defaultValue(SwingHand.RealHand) + .visible(placeSwing::get) + .build() + ); + private final Setting attackSwing = sgRender.add(new BoolSetting.Builder() + .name("Attack Swing") + .description("Renders swing animation when placing a crystal.") + .defaultValue(true) + .build() + ); + private final Setting attackHand = sgRender.add(new EnumSetting.Builder() + .name("Attack Hand") + .description("Which hand should be swung.") + .defaultValue(SwingHand.RealHand) + .visible(attackSwing::get) + .build() + ); + private final Setting render = sgRender.add(new BoolSetting.Builder() + .name("Render") + .description("Renders box on placement.") + .defaultValue(true) + .build() + ); + private final Setting renderMode = sgRender.add(new EnumSetting.Builder() + .name("Render Mode") + .description("What should the render look like.") + .defaultValue(RenderMode.BlackOut) + .build() + ); + private final Setting renderTime = sgRender.add(new DoubleSetting.Builder() + .name("Render Time") + .description("How long the box should remain in full alpha value.") + .defaultValue(0.3) + .min(0) + .sliderRange(0, 10) + .visible(() -> renderMode.get().equals(RenderMode.Earthhack) || renderMode.get().equals(RenderMode.Future)) + .build() + ); + private final Setting fadeMode = sgRender.add(new EnumSetting.Builder() + .name("Fade Mode") + .description("How long the fading should take.") + .defaultValue(FadeMode.Normal) + .visible(() -> renderMode.get() == RenderMode.BlackOut) + .build() + ); + private final Setting earthFadeMode = sgRender.add(new EnumSetting.Builder() + .name("Earth Fade Mode") + .description(".") + .defaultValue(EarthFadeMode.Normal) + .visible(() -> renderMode.get() == RenderMode.Earthhack) + .build() + ); + private final Setting fadeTime = sgRender.add(new DoubleSetting.Builder() + .name("Fade Time") + .description("How long the fading should take.") + .defaultValue(1) + .min(0) + .sliderRange(0, 10) + .visible(() -> renderMode.get().equals(RenderMode.Earthhack) || renderMode.get().equals(RenderMode.Future)) + .build() + ); + private final Setting animationSpeed = sgRender.add(new DoubleSetting.Builder() + .name("Animation Move Speed") + .description("How fast should blackout mode box move.") + .defaultValue(1) + .min(0) + .sliderRange(0, 10) + .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) + .build() + ); + private final Setting animationMoveExponent = sgRender.add(new DoubleSetting.Builder() + .name("Animation Move Exponent") + .description("Moves faster when longer away from the target.") + .defaultValue(2) + .min(0) + .sliderRange(0, 10) + .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) + .build() + ); + private final Setting animationExponent = sgRender.add(new DoubleSetting.Builder() + .name("Animation Exponent") + .description("How fast should blackout mode box grow.") + .defaultValue(3) + .min(0) + .sliderRange(0, 10) + .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) + .build() + ); + private final Setting shapeMode = sgRender.add(new EnumSetting.Builder() + .name("Shape Mode") + .description("Which parts of render should be rendered.") + .defaultValue(ShapeMode.Both) + .build() + ); + private final Setting lineColor = sgRender.add(new ColorSetting.Builder() + .name("Line Color") + .description("Line color of rendered boxes") + .defaultValue(new SettingColor(255, 0, 0, 255)) + .build() + ); + public final Setting color = sgRender.add(new ColorSetting.Builder() + .name("Side Color") + .description("Side color of rendered boxes") + .defaultValue(new SettingColor(255, 0, 0, 50)) + .build() + ); + + //--------------------Compatibility--------------------// + private final Setting autoMineDamage = sgCompatibility.add(new DoubleSetting.Builder() + .name("Auto Mine Damage") + .description("Prioritizes placing on automine target block.") + .defaultValue(1.1) + .min(1) + .sliderRange(1, 5) + .build() + ); + private final Setting amPlace = sgCompatibility.add(new BoolSetting.Builder() + .name("Auto Mine Place") + .description("Ignores automine block before if actually breaks.") + .defaultValue(true) + .build() + ); + private final Setting amProgress = sgCompatibility.add(new DoubleSetting.Builder() + .name("Auto Mine Progress") + .description("Ignores the block after it has reached this progress.") + .defaultValue(0.95) + .range(0, 1) + .sliderRange(0, 1) + .visible(amPlace::get) + .build() + ); + private final Setting amSpam = sgCompatibility.add(new BoolSetting.Builder() + .name("Auto Mine Spam") + .description("Spams crystals before the block breaks.") + .defaultValue(false) + .visible(amPlace::get) + .build() + ); + private final Setting amBroken = sgCompatibility.add(new EnumSetting.Builder() + .name("Auto Mine Broken") + .description("Doesn't place on automine block.") + .defaultValue(AutoMineBrokenMode.Near) + .build() + ); + private final Setting paAttack = sgCompatibility.add(new BoolSetting.Builder() + .name("Piston Crystal Attack") + .description("Doesn't attack the crystal placed by piston crystal.") + .defaultValue(true) + .build() + ); + private final Setting paPlace = sgCompatibility.add(new BoolSetting.Builder() + .name("Piston Crystal Placing") + .description("Doesn't place crystals when piston crystal is enabled.") + .defaultValue(true) + .build() + ); + + //--------------------Debug--------------------// + private final Setting renderExt = sgDebug.add(new BoolSetting.Builder() + .name("Render Extrapolation") + .description("Renders boxes at players' predicted positions.") + .defaultValue(false) + .build() + ); + private final Setting renderSelfExt = sgDebug.add(new BoolSetting.Builder() + .name("Render Self Extrapolation") + .description("Renders box at your predicted position.") + .defaultValue(false) + .build() + ); + + private long ticksEnabled = 0; + private double placeTimer = 0; + private double placeLimitTimer = 0; + private double delayTimer = 0; + private int delayTicks = 0; + + private BlockPos placePos = null; + private Direction placeDir = null; + private Entity expEntity = null; + private final TimerList attackedList = new TimerList<>(); + private final TimerList inhibitList = new TimerList<>(); + private final Map existedList = new HashMap<>(); + private final Map existedTicksList = new HashMap<>(); + private final Map own = new HashMap<>(); + private final Map extPos = new HashMap<>(); + private final Map extHitbox = new HashMap<>(); + private Vec3d rangePos = null; + private final List blocked = new ArrayList<>(); + private final Map earthMap = new HashMap<>(); + private double attackTimer = 0; + private double switchTimer = 0; + private int confirmed = Integer.MIN_VALUE; + private long lastMillis = System.currentTimeMillis(); + private boolean suicide = false; + public static boolean placing = false; + private long lastAttack = 0; + + private Vec3d renderTarget = null; + private Vec3d renderPos = null; + private double renderProgress = 0; + + private AutoMine autoMine = null; + + private int placed = 0; + + private double cps = 0; + private final List explosions = Collections.synchronizedList(new ArrayList<>()); + + private final List predicts = new ArrayList<>(); + private final List setDeads = new ArrayList<>(); + + @Override + public void onActivate() { + super.onActivate(); + ticksEnabled = 0; + + earthMap.clear(); + existedTicksList.clear(); + existedList.clear(); + blocked.clear(); + extPos.clear(); + own.clear(); + renderPos = null; + renderProgress = 0; + lastMillis = System.currentTimeMillis(); + attackedList.clear(); + lastAttack = 0; + + predicts.clear(); + setDeads.clear(); + } + + @Override + public String getInfoString() { + return String.format("%.1f", cps); + } + + @EventHandler(priority = EventPriority.HIGHEST) + private void onTickPost(TickEvent.Post event) { + delayTicks++; + ticksEnabled++; + placed++; + + if (mc.player == null || mc.world == null) return; + + if (autoMine == null) autoMine = Modules.get().get(AutoMine.class); + + ExtrapolationUtils.extrapolateMap(extPos, player -> player == mc.player ? selfExt.get() : extrapolation.get(), player -> extSmoothness.get()); + ExtrapolationUtils.extrapolateMap(extHitbox, player -> hitboxExtrapolation.get(), player -> extSmoothness.get()); + + Box rangeBox = ExtrapolationUtils.extrapolate(mc.player, rangeExtrapolation.get(), extSmoothness.get()); + if (rangeBox == null) rangePos = mc.player.getEyePos(); + else rangePos = new Vec3d((rangeBox.minX + rangeBox.maxX) / 2f, rangeBox.minY + mc.player.getEyeHeight(mc.player.getPose()), (rangeBox.minZ + rangeBox.maxZ) / 2f); + + List toRemove = new ArrayList<>(); + existedList.forEach((key, val) -> { + if (System.currentTimeMillis() - val >= 5000 + existed.get() * 1000) + toRemove.add(key); + }); + toRemove.forEach(existedList::remove); + + toRemove.clear(); + existedTicksList.forEach((key, val) -> { + if (ticksEnabled - val >= 100 + existedTicks.get()) + toRemove.add(key); + }); + toRemove.forEach(existedTicksList::remove); + + toRemove.clear(); + own.forEach((key, val) -> { + if (System.currentTimeMillis() - val >= 5000) + toRemove.add(key); + }); + toRemove.forEach(own::remove); + + if (performance.get()) updatePlacement(); + } + + @EventHandler(priority = EventPriority.HIGHEST + 1) + private void onRender3D(Render3DEvent event) { + attackedList.update(); + inhibitList.update(); + + if (autoMine == null) autoMine = Modules.get().get(AutoMine.class); + + suicide = Modules.get().isActive(Suicide.class); + double delta = (System.currentTimeMillis() - lastMillis) / 1000f; + lastMillis = System.currentTimeMillis(); + + cps = 0; + synchronized (explosions) { + explosions.removeIf(time -> { + double p = (System.currentTimeMillis() - time) / 1000D; + + if (p >= 5) return true; + + double d = p <= 4 ? 1 : 1 - (p - 4); + cps += d; + return false; + }); + } + cps /= 4.5; + + attackTimer = Math.max(attackTimer - delta, 0); + placeTimer = Math.max(placeTimer - delta * getSpeed(), 0); + placeLimitTimer += delta; + delayTimer += delta; + switchTimer = Math.max(0, switchTimer - delta); + + update(); + checkDelayed(); + + //Rendering + if (render.get()) { + switch (renderMode.get()) { + case BlackOut -> { + if (placePos != null && !isPaused() && holdingCheck()) { + renderProgress = Math.min(1, renderProgress + delta); + renderTarget = new Vec3d(placePos.getX(), placePos.getY(), placePos.getZ()); + } else { + renderProgress = Math.max(0, renderProgress - delta); + } + + if (renderTarget != null) { + renderPos = smoothMove(renderPos, renderTarget, delta * animationSpeed.get() * 5); + } + + if (renderPos != null) { + double r = 0.5 - Math.pow(1 - renderProgress, animationExponent.get()) / 2f; + + if (r >= 0.001) { + double down = -0.5; + double up = -0.5; + double width = 0.5; + + switch (fadeMode.get()) { + case Up -> { + up = 0; + down = -(r * 2); + } + case Down -> { + up = -1 + r * 2; + down = -1; + } + case Normal -> { + up = -0.5 + r; + down = -0.5 - r; + width = r; + } + } + Box box = new Box(renderPos.getX() + 0.5 - width, renderPos.getY() + down, renderPos.getZ() + 0.5 - width, + renderPos.getX() + 0.5 + width, renderPos.getY() + up, renderPos.getZ() + 0.5 + width); + + event.renderer.box(box, new Color(color.get().r, color.get().g, color.get().b, color.get().a), lineColor.get(), shapeMode.get(), 0); + } + } + } + case Future -> { + if (placePos != null && !isPaused() && holdingCheck()) { + renderPos = new Vec3d(placePos.getX(), placePos.getY(), placePos.getZ()); + renderProgress = fadeTime.get() + renderTime.get(); + } else { + renderProgress = Math.max(0, renderProgress - delta); + } + + if (renderProgress > 0 && renderPos != null) { + event.renderer.box(new Box(renderPos.getX(), renderPos.getY() - 1, renderPos.getZ(), + renderPos.getX() + 1, renderPos.getY(), renderPos.getZ() + 1), + new Color(color.get().r, color.get().g, color.get().b, (int) Math.round(color.get().a * Math.min(1, renderProgress / fadeTime.get()))), + new Color(lineColor.get().r, lineColor.get().g, lineColor.get().b, (int) Math.round(lineColor.get().a * Math.min(1, renderProgress / fadeTime.get()))), shapeMode.get(), 0); + } + } + case Earthhack -> { + List toRemove = new ArrayList<>(); + for (Map.Entry entry : earthMap.entrySet()) { + BlockPos pos = entry.getKey(); + Double[] alpha = entry.getValue(); + if (alpha[0] <= delta) { + toRemove.add(pos); + } else { + double r = Math.min(1, alpha[0] / alpha[1]) / 2f; + double down = -0.5; + double up = -0.5; + double width = 0.5; + + switch (earthFadeMode.get()) { + case Normal -> { + up = 1; + down = 0; + } + case Up -> { + up = 1; + down = 1 - (r * 2); + } + case Down -> { + up = r * 2; + down = 0; + } + case Shrink -> { + up = 0.5 + r; + down = 0.5 - r; + width = r; + } + } + + Box box = new Box(pos.getX() + 0.5 - width, pos.getY() + down, pos.getZ() + 0.5 - width, + pos.getX() + 0.5 + width, pos.getY() + up, pos.getZ() + 0.5 + width); + + event.renderer.box(box, + new Color(color.get().r, color.get().g, color.get().b, (int) Math.round(color.get().a * Math.min(1, alpha[0] / alpha[1]))), + new Color(lineColor.get().r, lineColor.get().g, lineColor.get().b, (int) Math.round(lineColor.get().a * Math.min(1, alpha[0] / alpha[1]))), shapeMode.get(), 0); + entry.setValue(new Double[]{alpha[0] - delta, alpha[1]}); + } + } + toRemove.forEach(earthMap::remove); + } + } + } + + if (mc.player != null) { + //Render extrapolation + if (renderExt.get()) { + extPos.forEach((name, bb) -> { + if (renderSelfExt.get() || !name.equals(mc.player)) + event.renderer.box(bb, color.get(), lineColor.get(), shapeMode.get(), 0); + }); + } + } + } + + @EventHandler(priority = EventPriority.HIGHEST) + private void onEntity(EntityAddedEvent event) { + confirmed = event.entity.getId(); + + if (event.entity.getBlockPos().equals(placePos)) explosions.add(System.currentTimeMillis()); + } + + @EventHandler(priority = EventPriority.HIGHEST) + private void onSend(PacketEvent.Send event) { + if (mc.player != null && mc.world != null) { + if (event.packet instanceof UpdateSelectedSlotC2SPacket) { + switchTimer = switchPenalty.get(); + } + + if (event.packet instanceof PlayerInteractBlockC2SPacket packet) { + + if (!(packet.getHand() == Hand.MAIN_HAND ? Managers.HOLDING.isHolding(Items.END_CRYSTAL) : mc.player.getOffHandStack().getItem() == Items.END_CRYSTAL)) + return; + + if (isOwn(packet.getBlockHitResult().getBlockPos().up())) own.remove(packet.getBlockHitResult().getBlockPos().up()); + + own.put(packet.getBlockHitResult().getBlockPos().up(), System.currentTimeMillis()); + blocked.add(OLEPOSSUtils.getCrystalBox(packet.getBlockHitResult().getBlockPos().up())); + addExisted(packet.getBlockHitResult().getBlockPos().up()); + } + } + } + + // Other stuff + private void update() { + placing = false; + expEntity = null; + + Hand hand = getHand(stack -> stack.getItem() == Items.END_CRYSTAL); + + Hand handToUse = hand; + if (!performance.get()) updatePlacement(); + + switch (switchMode.get()) { + case Simple -> { + int slot = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); + if (placePos != null && hand == null && slot >= 0) { + InvUtils.swap(slot, false); + handToUse = Hand.MAIN_HAND; + } + } + case Gapple -> { + int gapSlot = InvUtils.findInHotbar(OLEPOSSUtils::isGapple).slot(); + if (mc.options.useKey.isPressed() && Managers.HOLDING.isHolding(Items.END_CRYSTAL, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLDEN_APPLE) && gapSlot >= 0) { + if (getHand(OLEPOSSUtils::isGapple) == null) + InvUtils.swap(gapSlot, false); + handToUse = getHand(itemStack -> itemStack.getItem() == Items.END_CRYSTAL); + } else if (Managers.HOLDING.isHolding(Items.END_CRYSTAL, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLDEN_APPLE)) { + int slot = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); + if (placePos != null && hand == null && slot >= 0) { + InvUtils.swap(slot, false); + handToUse = Hand.MAIN_HAND; + } + } + } + } + + if (placePos != null && placeDir != null) { + if (!isPaused() && (!paPlace.get() || !Modules.get().isActive(PistonCrystal.class))) { + int silentSlot = InvUtils.find(itemStack -> itemStack.getItem() == Items.END_CRYSTAL).slot(); + int hotbar = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); + if (handToUse != null || (switchMode.get() == SwitchMode.Silent && hotbar >= 0) || ((switchMode.get() == SwitchMode.PickSilent || switchMode.get() == SwitchMode.InvSilent) && silentSlot >= 0)) { + placing = true; + if (!SettingUtils.shouldRotate(RotationType.Interact) || Managers.ROTATION.start(placePos.down(), smartRot.get() ? new Vec3d(placePos.getX() + 0.5, placePos.getY(), placePos.getZ() + 0.5) : null, priority, RotationType.Interact, Objects.hash(name + "placing"))) { + if (speedCheck() && delayCheck()) + placeCrystal(placePos.down(), placeDir, handToUse, silentSlot, hotbar); + } + } + } + } + + PistonCrystal pa = Modules.get().get(PistonCrystal.class); + double[] value = null; + + if (!isPaused() && (hand != null || switchMode.get() == SwitchMode.Silent || switchMode.get() == SwitchMode.PickSilent || switchMode.get() == SwitchMode.InvSilent) && explode.get()) { + for (Entity en : mc.world.getEntities()) { + if (!(en instanceof EndCrystalEntity)) continue; + if (paAttack.get() && pa.isActive() && en.getBlockPos().equals(pa.crystalPos)) continue; + if (inhibitList.contains(en.getId())) continue; + if (switchTimer > 0) continue; + + double[] dmg = getDmg(en.getPos(), true)[0]; + + if (!canExplode(en.getPos())) continue; + + if ((expEntity == null || value == null) || ((dmgCheckMode.get().equals(DmgCheckMode.Normal) && dmg[0] > value[0]) || (dmgCheckMode.get().equals(DmgCheckMode.Safe) && dmg[2] / dmg[0] < value[2] / dmg[0]))) { + expEntity = en; + value = dmg; + } + } + } + + if (expEntity != null) { + if (multiTaskCheck() && !isAttacked(expEntity.getId()) && attackDelayCheck() && existedCheck(expEntity.getBlockPos())) { + if (!SettingUtils.shouldRotate(RotationType.Attacking) || startAttackRot()) { + explode(expEntity.getId(), expEntity.getPos()); + } + } + } else if (SettingUtils.shouldRotate(RotationType.Attacking)) Managers.ROTATION.end(Objects.hash(name + "attacking")); + } + + private boolean attackDelayCheck() { + if (instantAttack.get()) + return expSpeedLimit.get() <= 0 || System.currentTimeMillis() > lastAttack + 1000 / expSpeedLimit.get(); + else + return System.currentTimeMillis() > lastAttack + 1000 / expSpeed.get(); + } + + private boolean startAttackRot() { + return (Managers.ROTATION.start(expEntity.getBoundingBox(), smartRot.get() ? expEntity.getPos() : null, priority + (!isAttacked(expEntity.getId()) && blocksPlacePos(expEntity) ? -0.1 : 0.1), RotationType.Attacking, Objects.hash(name + "attacking"))); + } + + private boolean blocksPlacePos(Entity entity) { + return placePos != null && entity.getBoundingBox().intersects(new Box(placePos.getX(), placePos.getY(), placePos.getZ(), placePos.getX() + 1, placePos.getY() + (SettingUtils.cc() ? 1 : 2), placePos.getZ() + 1)); + } + + private boolean isAlive(Box box) { + if (box == null) return true; + + for (Entity en : mc.world.getEntities()) { + if (!(en instanceof EndCrystalEntity)) continue; + if (bbEquals(box, en.getBoundingBox())) return true; + } + return false; + } + + private boolean bbEquals(Box box1, Box box2) { + return box1.minX == box2.minX && + box1.minY == box2.minY && + box1.minZ == box2.minZ && + box1.maxX == box2.maxX && + box1.maxY == box2.maxY && + box1.maxZ == box2.maxZ; + } + + private boolean speedCheck() { + + if (speedLimit.get() > 0 && placeLimitTimer < 1 / speedLimit.get()) + return false; + + if (instantPlace.get() && !shouldSlow() && !isBlocked(placePos)) + return true; + + return placeTimer <= 0; + } + + private boolean holdingCheck() { + return switch (switchMode.get()) { + case Silent -> InvUtils.findInHotbar(Items.END_CRYSTAL).slot() >= 0; + case PickSilent, InvSilent -> InvUtils.find(Items.END_CRYSTAL).slot() >= 0; + default -> getHand(itemStack -> itemStack.getItem() == Items.END_CRYSTAL) != null; + }; + } + + private void updatePlacement() { + if (!place.get()) { + placePos = null; + placeDir = null; + return; + } + placePos = getPlacePos(); + } + + private void placeCrystal(BlockPos pos, Direction dir, Hand handToUse, int sl, int hsl) { + if (pos != null && mc.player != null) { + if (renderMode.get().equals(RenderMode.Earthhack)) { + if (!earthMap.containsKey(pos)) + earthMap.put(pos, new Double[]{fadeTime.get() + renderTime.get(), fadeTime.get()}); + else + earthMap.replace(pos, new Double[]{fadeTime.get() + renderTime.get(), fadeTime.get()}); + } + + blocked.add(new Box(pos.getX() - 0.5, pos.getY() + 1, pos.getZ() - 0.5, pos.getX() + 1.5, pos.getY() + 2, pos.getZ() + 1.5)); + + boolean switched = handToUse == null; + if (switched) { + switch (switchMode.get()) { + case PickSilent -> BOInvUtils.pickSwitch(sl); + case Silent -> InvUtils.swap(hsl, true); + case InvSilent -> BOInvUtils.invSwitch(sl); + } + } + + addExisted(pos.up()); + + if (!isOwn(pos.up())) own.put(pos.up(), System.currentTimeMillis()); + else { + own.remove(pos.up()); + own.put(pos.up(), System.currentTimeMillis()); + } + + placeLimitTimer = 0; + placeTimer = 1; + placed = 0; + + interactBlock(switched ? Hand.MAIN_HAND : handToUse, pos.toCenterPos(), dir, pos); + + if (placeSwing.get()) clientSwing(placeHand.get(), switched ? Hand.MAIN_HAND : handToUse); + + if (SettingUtils.shouldRotate(RotationType.Interact)) + Managers.ROTATION.end(Objects.hash(name + "placing")); + + if (switched) { + switch (switchMode.get()) { + case PickSilent -> BOInvUtils.pickSwapBack(); + case Silent -> InvUtils.swapBack(); + case InvSilent -> BOInvUtils.swapBack(); + } + } + if (idPredict.get()) { + int highest = getHighest(); + + int id = highest + idStartOffset.get(); + for (int i = 0; i < idPackets.get() * idOffset.get(); i += idOffset.get()) { + addPredict(id + i, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), idDelay.get() + idPacketDelay.get() * i); + } + } + } + } + + private boolean delayCheck() { + if (placeDelayMode.get() == DelayMode.Seconds) + return delayTimer >= placeDelay.get(); + return delayTicks >= placeDelayTicks.get(); + } + + private boolean multiTaskCheck() { + return placed >= sequential.get().ticks; + } + + private int getHighest() { + int highest = confirmed; + for (Entity entity : mc.world.getEntities()) { + if (entity.getId() > highest) highest = entity.getId(); + } + if (highest > confirmed) confirmed = highest; + return highest; + } + + private boolean isBlocked(BlockPos pos) { + Box box = new Box(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1); + for (Box bb : blocked) { + if (bb.intersects(box)) return true; + } + return false; + } + + private boolean isAttacked(int id) { + return attackedList.contains(id); + } + + private void explode(int id, Vec3d vec) { + attackEntity(id, OLEPOSSUtils.getCrystalBox(vec), vec); + } + + private void attackEntity(int id, Box bb, Vec3d vec) { + if (mc.player != null) { + lastAttack = System.currentTimeMillis(); + attackedList.add(id, 1 / expSpeed.get()); + if (inhibit.get()) inhibitList.add(id, 0.5); + + delayTimer = 0; + delayTicks = 0; + + removeExisted(BlockPos.ofFloored(vec)); + + SettingUtils.registerAttack(bb); + PlayerInteractEntityC2SPacket packet = PlayerInteractEntityC2SPacket.attack(mc.player, mc.player.isSneaking()); + ((IInteractEntityC2SPacket) packet).setId(id); + + SettingUtils.swing(SwingState.Pre, SwingType.Attacking, Hand.MAIN_HAND); + + sendPacket(packet); + + SettingUtils.swing(SwingState.Post, SwingType.Attacking, Hand.MAIN_HAND); + if (attackSwing.get()) clientSwing(attackHand.get(), Hand.MAIN_HAND); + + blocked.clear(); + if (setDead.get()) { + Entity entity = mc.world.getEntityById(id); + if (entity == null) return; + + addSetDead(entity, setDeadDelay.get()); + } + } + } + + private boolean existedCheck(BlockPos pos) { + if (existedMode.get() == DelayMode.Seconds) + return !existedList.containsKey(pos) || System.currentTimeMillis() > existedList.get(pos) + existed.get() * 1000; + else + return !existedTicksList.containsKey(pos) || ticksEnabled >= existedTicksList.get(pos) + existedTicks.get(); + } + + private void addExisted(BlockPos pos) { + if (existedMode.get() == DelayMode.Seconds) { + if (!existedList.containsKey(pos)) existedList.put(pos, System.currentTimeMillis()); + } else { + if (!existedTicksList.containsKey(pos)) existedTicksList.put(pos, ticksEnabled); + } + } + + private void removeExisted(BlockPos pos) { + if (existedMode.get() == DelayMode.Seconds) existedList.remove(pos); + else existedTicksList.remove(pos); + } + + private boolean canExplode(Vec3d vec) { + if (onlyOwn.get() && !isOwn(vec)) return false; + if (!inExplodeRange(vec)) return false; + + double[][] result = getDmg(vec, true); + return explodeDamageCheck(result[0], result[1], isOwn(vec)); + } + + private boolean canExplodePlacing(Vec3d vec) { + if (onlyOwn.get() && !isOwn(vec)) return false; + if (!inExplodeRangePlacing(vec)) return false; + + double[][] result = getDmg(vec, false); + return explodeDamageCheck(result[0], result[1], isOwn(vec)); + } + + private Hand getHand(Predicate predicate) { + return predicate.test(Managers.HOLDING.getStack()) ? Hand.MAIN_HAND : + predicate.test(mc.player.getOffHandStack()) ? Hand.OFF_HAND : null; + } + + private boolean isPaused() { + return pauseEat.get() && mc.player.isUsingItem(); + } + + private void setEntityDead(Entity en) { + mc.world.removeEntity(en.getId(), Entity.RemovalReason.KILLED); + } + + private BlockPos getPlacePos() { + + int r = (int) Math.ceil(Math.max(SettingUtils.getPlaceRange(), SettingUtils.getPlaceWallsRange())); + //Used in placement calculation + BlockPos bestPos = null; + Direction bestDir = null; + double[] highest = null; + + BlockPos pPos = BlockPos.ofFloored(mc.player.getEyePos()); + + for (int x = -r; x <= r; x++) { + for (int y = -r; y <= r; y++) { + for (int z = -r; z <= r; z++) { + BlockPos pos = pPos.add(x, y, z); + // Checks if crystal can be placed + if (!air(pos) || !(!SettingUtils.oldCrystals() || air(pos.up())) || !crystalBlock(pos.down()) || blockBroken(pos.down())) continue; + + // Checks if there is possible placing direction + Direction dir = SettingUtils.getPlaceOnDirection(pos.down()); + if (dir == null) continue; + + // Checks if the placement is in range + if (!inPlaceRange(pos.down()) || !inExplodeRangePlacing(new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5))) continue; + + // Calculates damages and healths + double[][] result = getDmg(new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5), false); + + // Checks if damages are valid + if (!placeDamageCheck(result[0], result[1], highest)) continue; + + // Checks if placement is blocked by other entities (other than players) + Box box = new Box(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + (SettingUtils.cc() ? 1 : 2), pos.getZ() + 1); + + if (BOEntityUtils.intersectsWithEntity(box, this::validForIntersect, extHitbox)) continue; + + // Sets best pos to calculated one + bestDir = dir; + bestPos = pos; + highest = result[0]; + } + } + } + + placeDir = bestDir; + return bestPos; + } + + private boolean placeDamageCheck(double[] dmg, double[] health, double[] highest) { + // 0 = enemy, 1 = friend, 2 = self + + // Dmg Check + if (highest != null) { + if (dmgCheckMode.get().equals(DmgCheckMode.Normal) && dmg[0] < highest[0]) return false; + if (dmgCheckMode.get().equals(DmgCheckMode.Safe) && dmg[2] / dmg[0] > highest[2] / highest[0]) return false; + } + + // Force/anti-pop check + double playerHP = mc.player.getHealth() + mc.player.getAbsorptionAmount(); + + if (playerHP >= 0 && dmg[2] * antiSelfPop.get() >= playerHP) return false; + if (health[1] >= 0 && dmg[1] * antiFriendPop.get() >= health[1]) return false; + if (health[0] >= 0 && dmg[0] * forcePop.get() >= health[0]) return true; + + // Min Damage + if (dmg[0] < minPlace.get()) return false; + + // Max Damage + if (dmg[1] > maxFriendPlace.get()) return false; + if (dmg[1] >= 0 && dmg[0] / dmg[1] < minFriendPlaceRatio.get()) return false; + if (dmg[2] > maxPlace.get()) return false; + return dmg[2] < 0 || dmg[0] / dmg[2] >= minPlaceRatio.get(); + } + + private boolean explodeDamageCheck(double[] dmg, double[] health, boolean own) { + boolean checkOwn = expMode.get() == ExplodeMode.FullCheck + || expMode.get() == ExplodeMode.SelfDmgCheck + || expMode.get() == ExplodeMode.SelfDmgOwn + || expMode.get() == ExplodeMode.AlwaysOwn; + + boolean checkDmg = expMode.get() == ExplodeMode.FullCheck + || (expMode.get() == ExplodeMode.SelfDmgOwn && !own) + || (expMode.get() == ExplodeMode.AlwaysOwn && !own); + + // 0 = enemy, 1 = friend, 2 = self + + // Force/anti-pop check + double playerHP = mc.player.getHealth() + mc.player.getAbsorptionAmount(); + if (checkOwn) { + if (playerHP >= 0 && dmg[2] * forcePop.get() >= playerHP) return false; + if (health[1] >= 0 && dmg[1] * antiFriendPop.get() >= health[1]) return false; + } + + if (checkDmg) { + if (health[0] >= 0 && dmg[0] * forcePop.get() >= health[0]) return true; + if (dmg[0] < minExplode.get()) return false; + + if (dmg[1] >= 0 && dmg[0] / dmg[1] < minFriendExpRatio.get()) return false; + if (dmg[2] >= 0 && dmg[0] / dmg[2] < minExpRatio.get()) return false; + } + + if (checkOwn) { + if (dmg[1] > maxFriendExp.get()) return false; + return dmg[2] <= maxExp.get(); + } + return true; + } + + private boolean isOwn(Vec3d vec) { + return isOwn(BlockPos.ofFloored(vec)); + } + + private boolean isOwn(BlockPos pos) { + for (Map.Entry entry : own.entrySet()) { + if (entry.getKey().equals(pos)) return true; + } + return false; + } + + private double[][] getDmg(Vec3d vec, boolean attack) { + double self = BODamageUtils.crystalDamage(mc.player, extPos.containsKey(mc.player) ? extPos.get(mc.player) : mc.player.getBoundingBox(), vec, ignorePos(attack), ignoreTerrain.get()); + + if (suicide) return new double[][]{new double[]{self, -1, -1}, new double[]{20, 20}}; + + double highestEnemy = -1; + double highestFriend = -1; + double enemyHP = -1; + double friendHP = -1; + for (Map.Entry entry : extPos.entrySet()) { + AbstractClientPlayerEntity player = entry.getKey(); + Box box = entry.getValue(); + if (player.getHealth() <= 0 || player == mc.player) continue; + + double dmg = BODamageUtils.crystalDamage(player, box, vec, ignorePos(attack), ignoreTerrain.get()); + if (BlockPos.ofFloored(vec).down().equals(autoMine.targetPos())) + dmg *= autoMineDamage.get(); + double hp = player.getHealth() + player.getAbsorptionAmount(); + + // friend + if (Friends.get().isFriend(player)) { + if (dmg > highestFriend) { + highestFriend = dmg; + friendHP = hp; + } + } + // enemy + else if (dmg > highestEnemy) { + highestEnemy = dmg; + enemyHP = hp; + } + } + + return new double[][]{new double[]{highestEnemy, highestFriend, self}, new double[]{enemyHP, friendHP}}; + } + + private boolean air(BlockPos pos) { + return mc.world.getBlockState(pos).getBlock() instanceof AirBlock; + } + + private boolean crystalBlock(BlockPos pos) { + return mc.world.getBlockState(pos).getBlock().equals(Blocks.OBSIDIAN) || + mc.world.getBlockState(pos).getBlock().equals(Blocks.BEDROCK); + } + + private boolean inPlaceRange(BlockPos pos) { + return SettingUtils.inPlaceRange(pos); + } + + private boolean inExplodeRangePlacing(Vec3d vec) { + return SettingUtils.inAttackRange(new Box(vec.getX() - 1, vec.getY(), vec.getZ() - 1, vec.getX() + 1, vec.getY() + 2, vec.getZ() + 1), rangePos != null ? rangePos : null); + } + + private boolean inExplodeRange(Vec3d vec) { + return SettingUtils.inAttackRange(new Box(vec.getX() - 1, vec.getY(), vec.getZ() - 1, vec.getX() + 1, vec.getY() + 2, vec.getZ() + 1)); + } + + private double getSpeed() { + return shouldSlow() ? slowSpeed.get() : placeSpeed.get(); + } + + private boolean shouldSlow() { + return placePos != null && getDmg(new Vec3d(placePos.getX() + 0.5, placePos.getY(), placePos.getZ() + 0.5), false)[0][0] <= slowDamage.get(); + } + + private Vec3d smoothMove(Vec3d current, Vec3d target, double delta) { + if (current == null) return target; + + double absX = Math.abs(current.x - target.x); + double absY = Math.abs(current.y - target.y); + double absZ = Math.abs(current.z - target.z); + + double x = (absX + Math.pow(absX, animationMoveExponent.get() - 1)) * delta; + double y = (absX + Math.pow(absY, animationMoveExponent.get() - 1)) * delta; + double z = (absX + Math.pow(absZ, animationMoveExponent.get() - 1)) * delta; + + return new Vec3d(current.x > target.x ? Math.max(target.x, current.x - x) : Math.min(target.x, current.x + x), + current.y > target.y ? Math.max(target.y, current.y - y) : Math.min(target.y, current.y + y), + current.z > target.z ? Math.max(target.z, current.z - z) : Math.min(target.z, current.z + z)); + } + + private boolean validForIntersect(Entity entity) { + if (entity instanceof EndCrystalEntity && canExplodePlacing(entity.getPos())) + return false; + + return !(entity instanceof PlayerEntity) || !entity.isSpectator(); + } + + private BlockPos ignorePos(boolean attack) { + if (!amPlace.get()) return null; + if (!amSpam.get() && attack) return null; + if (autoMine == null || !autoMine.isActive()) return null; + if (autoMine.targetPos() == null) return null; + + return autoMine.getMineProgress() > amProgress.get() ? autoMine.targetPos() : null; + } + + private boolean blockBroken(BlockPos pos) { + if (!amPlace.get()) return false; + + if (autoMine == null || !autoMine.isActive()) return false; + if (autoMine.targetPos() == null) return false; + if (!autoMine.targetPos().equals(pos)) return false; + + double progress = autoMine.getMineProgress(); + + if (progress >= 1 && !amBroken.get().broken) return true; + if (progress >= amProgress.get() && !amBroken.get().near) return true; + return progress < amProgress.get() && !amBroken.get().normal; + } + + private void addPredict(int id, Vec3d pos, double delay) { + predicts.add(new Predict(id, pos, Math.round(System.currentTimeMillis() + delay * 1000))); + } + + private void addSetDead(Entity entity, double delay) { + setDeads.add(new SetDead(entity, Math.round(System.currentTimeMillis() + delay * 1000))); + } + + private void checkDelayed() { + List toRemove = new ArrayList<>(); + for (Predict p : predicts) { + if (System.currentTimeMillis() >= p.time) { + explode(p.id, p.pos); + toRemove.add(p); + } + } + toRemove.forEach(predicts::remove); + + List toRemove2 = new ArrayList<>(); + for (SetDead p : setDeads) { + if (System.currentTimeMillis() >= p.time) { + setEntityDead(p.entity); + toRemove2.add(p); + } + } + toRemove2.forEach(setDeads::remove); + } + + public enum DmgCheckMode { + Normal, + Safe + } + + public enum RenderMode { + BlackOut, + Future, + Earthhack + } + + public enum SwitchMode { + Disabled, + Simple, + Gapple, + Silent, + InvSilent, + PickSilent + } + + public enum SequentialMode { + Disabled(0), + Weak(1), + Strong(2), + Strict(3); + + public final int ticks; + + SequentialMode(int ticks) { + this.ticks = ticks; + } + } + + public enum ExplodeMode { + FullCheck, + SelfDmgCheck, + SelfDmgOwn, + AlwaysOwn, + Always + } + + public enum DelayMode { + Seconds, + Ticks + } + + public enum EarthFadeMode { + Normal, + Up, + Down, + Shrink + } + + public enum FadeMode { + Up, + Down, + Normal + } + + public enum AutoMineBrokenMode { + Near(true, false, false), + Broken(true, true, false), + Never(false, false, false), + Always(true, true, true); + + public final boolean normal; + public final boolean near; + public final boolean broken; + + AutoMineBrokenMode(boolean normal, boolean near, boolean broken) { + this.normal = normal; + this.near = near; + this.broken = broken; + } + } + + private record Predict(int id, Vec3d pos, long time) { + } + + private record SetDead(Entity entity, long time) { + } +} diff --git a/src/main/java/com/genyo/addon/modules/GenyoAutoEZ.java b/src/main/java/com/genyo/addon/modules/GenyoAutoEZ.java index 45056e7..70d59ce 100644 --- a/src/main/java/com/genyo/addon/modules/GenyoAutoEZ.java +++ b/src/main/java/com/genyo/addon/modules/GenyoAutoEZ.java @@ -4,14 +4,10 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.ChatUtils; -import meteordevelopment.meteorclient.utils.player.PlayerUtils; import meteordevelopment.orbit.EventHandler; import meteordevelopment.orbit.EventPriority; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket; @@ -46,7 +42,7 @@ public GenyoAutoEZ() { private final Setting pop = sgGeneral.add(new BoolSetting.Builder() .name("Pop") - .description("Should we send a message when enemy pops a totem") + .description("nyugi ez nem csinál semmit, csak dísznek van XD") .defaultValue(true) .build() ); @@ -61,23 +57,16 @@ public GenyoAutoEZ() { private final Setting> popMessages = sgGeneral.add(new StringListSetting.Builder() .name("Pop Messages") .description("Messages to send when popping an enemy") - .defaultValue(List.of("ez pop ", "pop ", "i love kiwi pop ")) + .defaultValue(List.of("ez pop ", "pop ", "i love kiwi pop ")) .build() ); private final Random r = new Random(); private int lastPop; private final List messageQueue = new LinkedList<>(); - private HashMap taggedPlayers = new HashMap(); + private final HashMap taggedPlayers = new HashMap<>(); private int timer = 0; - - private AbstractClientPlayerEntity target; - - private String renderName = null; - private float renderHealth; - private float renderPing; - @Override public void onActivate() { super.onActivate(); @@ -94,58 +83,27 @@ private void onTick(TickEvent.Pre event) { timer = 0; if (msg.kill) messageQueue.clear(); - else messageQueue.remove(0); + else messageQueue.removeFirst(); } } } - private void updateTarget() { - target = null; - if (mc.world == null) {return;} - - AbstractClientPlayerEntity closest = null; - double distance = Double.MAX_VALUE; - - for (AbstractClientPlayerEntity player : mc.world.getPlayers()) { - if (player == mc.player) {continue;} - if (Friends.get().isFriend(player)) {continue;} - - double d = mc.player.distanceTo(player); - - if (d < distance) { - closest = player; - distance = d; - } - } - - target = closest; - - if (target != null) { - renderName = target.getName().getString(); - renderHealth = target.getHealth() + target.getAbsorptionAmount(); - - PlayerListEntry playerListEntry = mc.getNetworkHandler().getPlayerListEntry(target.getUuid()); - renderPing = playerListEntry == null ? -1 : playerListEntry.getLatency(); - } - } - @EventHandler private void onReceive(PacketEvent.Receive event) { if (event.packet instanceof EntityStatusS2CPacket packet) { // Pop if (packet.getStatus() == 35) { Entity entity = packet.getEntity(mc.world); - if (pop.get() && mc.player != null && mc.world != null && entity instanceof PlayerEntity playerEntity) { - if (entity != mc.player && !Friends.get().isFriend((PlayerEntity) entity) && - mc.player.getPos().distanceTo(entity.getPos()) <= range.get()) { + if (mc.player != null && mc.world != null && entity instanceof PlayerEntity playerEntity) { + if (entity != mc.player && mc.player.getPos().distanceTo(entity.getPos()) <= range.get()) { if (trackPlayers.get() && taggedPlayers.containsKey(playerEntity)) { - int count = taggedPlayers.get(entity) + 1; + int count = taggedPlayers.get(playerEntity) + 1; taggedPlayers.replace(playerEntity, count); - sendPopMessage(entity.getName().getString(), count); + sendPopMessage(playerEntity.getName().getString(), count); } else { - sendPopMessage(entity.getName().getString(), 0); + sendPopMessage(playerEntity.getName().getString(), 0); taggedPlayers.put(playerEntity, 1); } } @@ -156,15 +114,18 @@ private void onReceive(PacketEvent.Receive event) { private void sendPopMessage(String name, int count) { if (!popMessages.get().isEmpty()) { - int num = r.nextInt(0, popMessages.get().size() - 1); + int num = r.nextInt(0, popMessages.get().size()); if (num == lastPop) { num = num < popMessages.get().size() - 1 ? num + 1 : 0; } lastPop = num; String messageString = popMessages.get().get(num).replace("", name); + String countString = String.valueOf(count); if (count > 0) { - messageString += " +" + count; + messageString = messageString.replace("", "+" + countString); + } else { + messageString = messageString.replace("", "+1"); } Message message = new Message(messageString, false); diff --git a/src/main/java/com/genyo/addon/modules/GenyoKristaj.java b/src/main/java/com/genyo/addon/modules/GenyoKristaj.java new file mode 100644 index 0000000..ddae830 --- /dev/null +++ b/src/main/java/com/genyo/addon/modules/GenyoKristaj.java @@ -0,0 +1,1385 @@ +package com.genyo.addon.modules; + +import com.genyo.addon.GenyoAddon; +import com.google.common.util.concurrent.AtomicDouble; +import it.unimi.dsi.fastutil.ints.*; +import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; +import meteordevelopment.meteorclient.events.entity.EntityRemovedEvent; +import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.meteorclient.events.render.Render2DEvent; +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.events.world.TickEvent; +import meteordevelopment.meteorclient.mixininterface.IBox; +import meteordevelopment.meteorclient.mixininterface.IRaycastContext; +import meteordevelopment.meteorclient.mixininterface.IVec3d; +import meteordevelopment.meteorclient.renderer.ShapeMode; +import meteordevelopment.meteorclient.renderer.text.TextRenderer; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.combat.BedAura; +import meteordevelopment.meteorclient.utils.entity.DamageUtils; +import meteordevelopment.meteorclient.utils.entity.EntityUtils; +import meteordevelopment.meteorclient.utils.entity.Target; +import meteordevelopment.meteorclient.utils.misc.Keybind; +import meteordevelopment.meteorclient.utils.player.FindItemResult; +import meteordevelopment.meteorclient.utils.player.InvUtils; +import meteordevelopment.meteorclient.utils.player.PlayerUtils; +import meteordevelopment.meteorclient.utils.player.Rotations; +import meteordevelopment.meteorclient.utils.render.NametagUtils; +import meteordevelopment.meteorclient.utils.render.RenderUtils; +import meteordevelopment.meteorclient.utils.render.color.Color; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import meteordevelopment.meteorclient.utils.world.BlockIterator; +import meteordevelopment.meteorclient.utils.world.BlockUtils; +import meteordevelopment.meteorclient.utils.world.TickRate; +import meteordevelopment.orbit.EventHandler; +import meteordevelopment.orbit.EventPriority; +import net.minecraft.block.Blocks; +import net.minecraft.component.type.AttributeModifierSlot; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.decoration.EndCrystalEntity; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.network.packet.c2s.play.*; +import net.minecraft.util.Hand; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.util.math.*; +import net.minecraft.world.RaycastContext; +import org.joml.Vector3d; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; + +public class GenyoKristaj extends Module { + + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + private final SettingGroup sgSwitch = settings.createGroup("Switch"); + private final SettingGroup sgPlace = settings.createGroup("Place"); + private final SettingGroup sgFacePlace = settings.createGroup("Face Place"); + private final SettingGroup sgBreak = settings.createGroup("Break"); + private final SettingGroup sgPause = settings.createGroup("Pause"); + private final SettingGroup sgRender = settings.createGroup("Render"); + + // General + + private final Setting targetRange = sgGeneral.add(new DoubleSetting.Builder() + .name("target-range") + .description("Range in which to target players.") + .defaultValue(10) + .min(0) + .sliderMax(16) + .build() + ); + + private final Setting predictMovement = sgGeneral.add(new BoolSetting.Builder() + .name("predict-movement") + .description("Predicts target movement.") + .defaultValue(false) + .build() + ); + + private final Setting minDamage = sgGeneral.add(new DoubleSetting.Builder() + .name("min-damage") + .description("Minimum damage the crystal needs to deal to your target.") + .defaultValue(6) + .min(0) + .build() + ); + + private final Setting maxDamage = sgGeneral.add(new DoubleSetting.Builder() + .name("max-damage") + .description("Maximum damage crystals can deal to yourself.") + .defaultValue(6) + .range(0, 36) + .sliderMax(36) + .build() + ); + + private final Setting antiSuicide = sgGeneral.add(new BoolSetting.Builder() + .name("anti-suicide") + .description("Will not place and break crystals if they will kill you.") + .defaultValue(true) + .build() + ); + + private final Setting ignoreNakeds = sgGeneral.add(new BoolSetting.Builder() + .name("ignore-nakeds") + .description("Ignore players with no items.") + .defaultValue(false) + .build() + ); + + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() + .name("rotate") + .description("Rotates server-side towards the crystals being hit/placed.") + .defaultValue(true) + .build() + ); + + private final Setting yawStepMode = sgGeneral.add(new EnumSetting.Builder() + .name("yaw-steps-mode") + .description("When to run the yaw steps check.") + .defaultValue(YawStepMode.Break) + .visible(rotate::get) + .build() + ); + + private final Setting yawSteps = sgGeneral.add(new DoubleSetting.Builder() + .name("yaw-steps") + .description("Maximum number of degrees its allowed to rotate in one tick.") + .defaultValue(180) + .range(1, 180) + .visible(rotate::get) + .build() + ); + + private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + .name("entities") + .description("Entities to attack.") + .onlyAttackable() + .defaultValue(EntityType.PLAYER, EntityType.WARDEN, EntityType.WITHER) + .build() + ); + + // Switch + + private final Setting autoSwitch = sgSwitch.add(new EnumSetting.Builder() + .name("auto-switch") + .description("Switches to crystals in your hotbar once a target is found.") + .defaultValue(AutoSwitchMode.Normal) + .build() + ); + + private final Setting switchDelay = sgSwitch.add(new IntSetting.Builder() + .name("switch-delay") + .description("The delay in ticks to wait to break a crystal after switching hotbar slot.") + .defaultValue(0) + .min(0) + .build() + ); + + private final Setting noGapSwitch = sgSwitch.add(new BoolSetting.Builder() + .name("no-gap-switch") + .description("Won't auto switch if you're holding a gapple.") + .defaultValue(true) + .visible(() -> autoSwitch.get() == AutoSwitchMode.Normal) + .build() + ); + + private final Setting noBowSwitch = sgSwitch.add(new BoolSetting.Builder() + .name("no-bow-switch") + .description("Won't auto switch if you're holding a bow.") + .defaultValue(true) + .build() + ); + + private final Setting antiWeakness = sgSwitch.add(new BoolSetting.Builder() + .name("anti-weakness") + .description("Switches to tools with so you can break crystals with the weakness effect.") + .defaultValue(true) + .build() + ); + + // Place + + private final Setting doPlace = sgPlace.add(new BoolSetting.Builder() + .name("place") + .description("If the CA should place crystals.") + .defaultValue(true) + .build() + ); + + public final Setting placeDelay = sgPlace.add(new IntSetting.Builder() + .name("place-delay") + .description("The delay in ticks to wait to place a crystal after it's exploded.") + .defaultValue(0) + .min(0) + .sliderMax(20) + .build() + ); + + private final Setting placeRange = sgPlace.add(new DoubleSetting.Builder() + .name("place-range") + .description("Range in which to place crystals.") + .defaultValue(4.5) + .min(0) + .sliderMax(6) + .build() + ); + + private final Setting placeWallsRange = sgPlace.add(new DoubleSetting.Builder() + .name("walls-range") + .description("Range in which to place crystals when behind blocks.") + .defaultValue(4.5) + .min(0) + .sliderMax(6) + .build() + ); + + private final Setting placement112 = sgPlace.add(new BoolSetting.Builder() + .name("1.12-placement") + .description("Uses 1.12 crystal placement.") + .defaultValue(false) + .build() + ); + + private final Setting support = sgPlace.add(new EnumSetting.Builder() + .name("support") + .description("Places a support block in air if no other position have been found.") + .defaultValue(SupportMode.Disabled) + .build() + ); + + private final Setting supportDelay = sgPlace.add(new IntSetting.Builder() + .name("support-delay") + .description("Delay in ticks after placing support block.") + .defaultValue(1) + .min(0) + .visible(() -> support.get() != SupportMode.Disabled) + .build() + ); + + // Face place + + private final Setting facePlace = sgFacePlace.add(new BoolSetting.Builder() + .name("face-place") + .description("Will face-place when target is below a certain health or armor durability threshold.") + .defaultValue(true) + .build() + ); + + private final Setting facePlaceHealth = sgFacePlace.add(new DoubleSetting.Builder() + .name("face-place-health") + .description("The health the target has to be at to start face placing.") + .defaultValue(8) + .min(1) + .sliderMin(1) + .sliderMax(36) + .visible(facePlace::get) + .build() + ); + + private final Setting facePlaceDurability = sgFacePlace.add(new DoubleSetting.Builder() + .name("face-place-durability") + .description("The durability threshold percentage to be able to face-place.") + .defaultValue(2) + .min(1) + .sliderMin(1) + .sliderMax(100) + .visible(facePlace::get) + .build() + ); + + private final Setting facePlaceArmor = sgFacePlace.add(new BoolSetting.Builder() + .name("face-place-missing-armor") + .description("Automatically starts face placing when a target misses a piece of armor.") + .defaultValue(false) + .visible(facePlace::get) + .build() + ); + + private final Setting forceFacePlace = sgFacePlace.add(new KeybindSetting.Builder() + .name("force-face-place") + .description("Starts face place when this button is pressed.") + .defaultValue(Keybind.none()) + .build() + ); + + // Break + + private final Setting doBreak = sgBreak.add(new BoolSetting.Builder() + .name("break") + .description("If the CA should break crystals.") + .defaultValue(true) + .build() + ); + + private final Setting breakDelay = sgBreak.add(new IntSetting.Builder() + .name("break-delay") + .description("The delay in ticks to wait to break a crystal after it's placed.") + .defaultValue(0) + .min(0) + .sliderMax(20) + .build() + ); + + private final Setting smartDelay = sgBreak.add(new BoolSetting.Builder() + .name("smart-delay") + .description("Only breaks crystals when the target can receive damage.") + .defaultValue(false) + .build() + ); + + private final Setting breakRange = sgBreak.add(new DoubleSetting.Builder() + .name("break-range") + .description("Range in which to break crystals.") + .defaultValue(4.5) + .min(0) + .sliderMax(6) + .build() + ); + + private final Setting breakWallsRange = sgBreak.add(new DoubleSetting.Builder() + .name("walls-range") + .description("Range in which to break crystals when behind blocks.") + .defaultValue(4.5) + .min(0) + .sliderMax(6) + .build() + ); + + private final Setting onlyBreakOwn = sgBreak.add(new BoolSetting.Builder() + .name("only-own") + .description("Only breaks own crystals.") + .defaultValue(false) + .build() + ); + + private final Setting breakAttempts = sgBreak.add(new IntSetting.Builder() + .name("break-attempts") + .description("How many times to hit a crystal before stopping to target it.") + .defaultValue(2) + .sliderMin(1) + .sliderMax(5) + .build() + ); + + private final Setting ticksExisted = sgBreak.add(new IntSetting.Builder() + .name("ticks-existed") + .description("Amount of ticks a crystal needs to have lived for it to be attacked by CrystalAura.") + .defaultValue(0) + .min(0) + .build() + ); + + private final Setting attackFrequency = sgBreak.add(new IntSetting.Builder() + .name("attack-frequency") + .description("Maximum hits to do per second.") + .defaultValue(25) + .min(1) + .sliderRange(1, 30) + .build() + ); + + private final Setting fastBreak = sgBreak.add(new BoolSetting.Builder() + .name("fast-break") + .description("Ignores break delay and tries to break the crystal as soon as it's spawned in the world.") + .defaultValue(true) + .build() + ); + + // Pause + + public final Setting pauseOnUse = sgPause.add(new EnumSetting.Builder() + .name("pause-on-use") + .description("Which processes should be paused while using an item.") + .defaultValue(PauseMode.Place) + .build() + ); + + public final Setting pauseOnMine = sgPause.add(new EnumSetting.Builder() + .name("pause-on-mine") + .description("Which processes should be paused while mining a block.") + .defaultValue(PauseMode.None) + .build() + ); + + private final Setting pauseOnLag = sgPause.add(new BoolSetting.Builder() + .name("pause-on-lag") + .description("Whether to pause if the server is not responding.") + .defaultValue(true) + .build() + ); + + public final Setting> pauseModules = sgPause.add(new ModuleListSetting.Builder() + .name("pause-modules") + .description("Pauses while any of the selected modules are active.") + .defaultValue(BedAura.class) + .build() + ); + + public final Setting pauseHealth = sgPause.add(new DoubleSetting.Builder() + .name("pause-health") + .description("Pauses when you go below a certain health.") + .defaultValue(5) + .range(0,36) + .sliderRange(0,36) + .build() + ); + + // Render + + public final Setting swingMode = sgRender.add(new EnumSetting.Builder() + .name("swing-mode") + .description("How to swing when placing.") + .defaultValue(SwingMode.Both) + .build() + ); + + private final Setting renderMode = sgRender.add(new EnumSetting.Builder() + .name("render-mode") + .description("The mode to render in.") + .defaultValue(RenderMode.Normal) + .build() + ); + + private final Setting renderPlace = sgRender.add(new BoolSetting.Builder() + .name("render-place") + .description("Renders a block overlay over the block the crystals are being placed on.") + .defaultValue(true) + .visible(() -> renderMode.get() == RenderMode.Normal) + .build() + ); + + private final Setting placeRenderTime = sgRender.add(new IntSetting.Builder() + .name("place-time") + .description("How long to render placements.") + .defaultValue(10) + .min(0) + .sliderMax(20) + .visible(() -> renderMode.get() == RenderMode.Normal && renderPlace.get()) + .build() + ); + + private final Setting renderBreak = sgRender.add(new BoolSetting.Builder() + .name("render-break") + .description("Renders a block overlay over the block the crystals are broken on.") + .defaultValue(false) + .visible(() -> renderMode.get() == RenderMode.Normal) + .build() + ); + + private final Setting breakRenderTime = sgRender.add(new IntSetting.Builder() + .name("break-time") + .description("How long to render breaking for.") + .defaultValue(13) + .min(0) + .sliderMax(20) + .visible(() -> renderMode.get() == RenderMode.Normal && renderBreak.get()) + .build() + ); + + private final Setting smoothness = sgRender.add(new IntSetting.Builder() + .name("smoothness") + .description("How smoothly the render should move around.") + .defaultValue(10) + .min(0) + .sliderMax(20) + .visible(() -> renderMode.get() == RenderMode.Smooth) + .build() + ); + + private final Setting height = sgRender.add(new DoubleSetting.Builder() + .name("height") + .description("How tall the gradient should be.") + .defaultValue(0.7) + .min(0) + .sliderMax(1) + .visible(() -> renderMode.get() == RenderMode.Gradient) + .build() + ); + + private final Setting renderTime = sgRender.add(new IntSetting.Builder() + .name("render-time") + .description("How long to render placements.") + .defaultValue(10) + .min(0) + .sliderMax(20) + .visible(() -> renderMode.get() == RenderMode.Smooth || renderMode.get() == RenderMode.Fading) + .build() + ); + + private final Setting shapeMode = sgRender.add(new EnumSetting.Builder() + .name("shape-mode") + .description("How the shapes are rendered.") + .defaultValue(ShapeMode.Both) + .visible(() -> renderMode.get() != RenderMode.None) + .build() + ); + + private final Setting sideColor = sgRender.add(new ColorSetting.Builder() + .name("side-color") + .description("The side color of the block overlay.") + .defaultValue(new SettingColor(255, 255, 255, 45)) + .visible(() -> shapeMode.get().sides() && renderMode.get() != RenderMode.None) + .build() + ); + + private final Setting lineColor = sgRender.add(new ColorSetting.Builder() + .name("line-color") + .description("The line color of the block overlay.") + .defaultValue(new SettingColor(255, 255, 255)) + .visible(() -> shapeMode.get().lines() && renderMode.get() != RenderMode.None) + .build() + ); + + private final Setting renderDamageText = sgRender.add(new BoolSetting.Builder() + .name("damage") + .description("Renders crystal damage text in the block overlay.") + .defaultValue(true) + .visible(() -> renderMode.get() != RenderMode.None) + .build() + ); + + private final Setting damageColor = sgRender.add(new ColorSetting.Builder() + .name("damage-color") + .description("The color of the damage text.") + .defaultValue(new SettingColor(255, 255, 255)) + .visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()) + .build() + ); + + private final Setting damageTextScale = sgRender.add(new DoubleSetting.Builder() + .name("damage-scale") + .description("How big the damage text should be.") + .defaultValue(1.25) + .min(1) + .sliderMax(4) + .visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()) + .build() + ); + + // Fields + + private Item mainItem, offItem; + + private int breakTimer, placeTimer, switchTimer, ticksPassed; + private final List targets = new ArrayList<>(); + + private final Vec3d vec3d = new Vec3d(0, 0, 0); + private final Vec3d playerEyePos = new Vec3d(0, 0, 0); + private final Vector3d vec3 = new Vector3d(); + private final BlockPos.Mutable blockPos = new BlockPos.Mutable(); + private final Box box = new Box(0, 0, 0, 0, 0, 0); + + private final Vec3d vec3dRayTraceEnd = new Vec3d(0, 0, 0); + private RaycastContext raycastContext; + + private final IntSet placedCrystals = new IntOpenHashSet(); + private boolean placing; + private int placingTimer; + public int kaTimer; + private final BlockPos.Mutable placingCrystalBlockPos = new BlockPos.Mutable(); + + private final IntSet removed = new IntOpenHashSet(); + private final Int2IntMap attemptedBreaks = new Int2IntOpenHashMap(); + private final Int2IntMap waitingToExplode = new Int2IntOpenHashMap(); + private int attacks; + + private double serverYaw; + + private LivingEntity bestTarget; + private double bestTargetDamage; + private int bestTargetTimer; + + private boolean didRotateThisTick; + private boolean isLastRotationPos; + private final Vec3d lastRotationPos = new Vec3d(0, 0 ,0); + private double lastYaw, lastPitch; + private int lastRotationTimer; + + private int placeRenderTimer, breakRenderTimer; + private final BlockPos.Mutable placeRenderPos = new BlockPos.Mutable(); + private final BlockPos.Mutable breakRenderPos = new BlockPos.Mutable(); + private Box renderBoxOne, renderBoxTwo; + + private double renderDamage; + + public GenyoKristaj() { + super(GenyoAddon.GENYO, "genyo-kristaj", "ez jobb mert a több az mindig jobb."); + } + + @Override + public void onActivate() { + breakTimer = 0; + placeTimer = 0; + ticksPassed = 0; + + raycastContext = new RaycastContext(new Vec3d(0, 0, 0), new Vec3d(0, 0, 0), RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player); + + placing = false; + placingTimer = 0; + kaTimer = 0; + + attacks = 0; + + serverYaw = mc.player.getYaw(); + + bestTargetDamage = 0; + bestTargetTimer = 0; + + lastRotationTimer = getLastRotationStopDelay(); + + placeRenderTimer = 0; + breakRenderTimer = 0; + } + + @Override + public void onDeactivate() { + targets.clear(); + + placedCrystals.clear(); + + attemptedBreaks.clear(); + waitingToExplode.clear(); + + removed.clear(); + + bestTarget = null; + } + + private int getLastRotationStopDelay() { + return Math.max(10, placeDelay.get() / 2 + breakDelay.get() / 2 + 10); + } + + @EventHandler(priority = EventPriority.HIGH) + private void onPreTick(TickEvent.Pre event) { + // Update last rotation + didRotateThisTick = false; + lastRotationTimer++; + + // Decrement placing timer + if (placing) { + if (placingTimer > 0) placingTimer--; + else placing = false; + } + + if (kaTimer > 0) kaTimer--; + + if (ticksPassed < 20) ticksPassed++; + else { + ticksPassed = 0; + attacks = 0; + } + + // Decrement best target timer + if (bestTargetTimer > 0) bestTargetTimer--; + bestTargetDamage = 0; + + // Decrement break, place and switch timers + if (breakTimer > 0) breakTimer--; + if (placeTimer > 0) placeTimer--; + if (switchTimer > 0) switchTimer--; + + // Decrement render timers + if (placeRenderTimer > 0) placeRenderTimer--; + if (breakRenderTimer > 0) breakRenderTimer--; + + mainItem = mc.player.getMainHandStack().getItem(); + offItem = mc.player.getOffHandStack().getItem(); + + // Update waiting to explode crystals and mark them as existing if reached threshold + for (IntIterator it = waitingToExplode.keySet().iterator(); it.hasNext();) { + int id = it.nextInt(); + int ticks = waitingToExplode.get(id); + + if (ticks > 3) { + it.remove(); + removed.remove(id); + } + else { + waitingToExplode.put(id, ticks + 1); + } + } + + // Set player eye pos + ((IVec3d) playerEyePos).meteor$set(mc.player.getPos().x, mc.player.getPos().y + mc.player.getEyeHeight(mc.player.getPose()), mc.player.getPos().z); + + // Find targets, break and place + findTargets(); + + if (!targets.isEmpty()) { + if (!didRotateThisTick) doBreak(); + if (!didRotateThisTick) doPlace(); + } + } + + @EventHandler + private void onEntityAdded(EntityAddedEvent event) { + if (!(event.entity instanceof EndCrystalEntity)) return; + + if (placing && event.entity.getBlockPos().equals(placingCrystalBlockPos)) { + placing = false; + placingTimer = 0; + placedCrystals.add(event.entity.getId()); + } + + if (fastBreak.get() && !didRotateThisTick && attacks < attackFrequency.get()) { + float damage = getBreakDamage(event.entity, true); + if (damage > minDamage.get()) doBreak(event.entity); + } + } + + @EventHandler + private void onEntityRemoved(EntityRemovedEvent event) { + if (event.entity instanceof EndCrystalEntity) { + placedCrystals.remove(event.entity.getId()); + removed.remove(event.entity.getId()); + waitingToExplode.remove(event.entity.getId()); + } + } + + private void setRotation(boolean isPos, Vec3d pos, double yaw, double pitch) { + didRotateThisTick = true; + isLastRotationPos = isPos; + + if (isPos) ((IVec3d) lastRotationPos).meteor$set(pos.x, pos.y, pos.z); + else { + lastYaw = yaw; + lastPitch = pitch; + } + + lastRotationTimer = 0; + } + + // Break + + private void doBreak() { + if (!doBreak.get() || breakTimer > 0 || switchTimer > 0 || attacks >= attackFrequency.get()) return; + if (shouldPause(PauseMode.Break)) return; + + float bestDamage = 0; + Entity crystal = null; + + // Find best crystal to break + for (Entity entity : mc.world.getEntities()) { + float damage = getBreakDamage(entity, true); + + if (damage > bestDamage) { + bestDamage = damage; + crystal = entity; + } + } + + // Break the crystal + if (crystal != null) doBreak(crystal); + } + + private float getBreakDamage(Entity entity, boolean checkCrystalAge) { + if (!(entity instanceof EndCrystalEntity)) return 0; + + // Check only break own + if (onlyBreakOwn.get() && !placedCrystals.contains(entity.getId())) return 0; + + // Check if it should already be removed + if (removed.contains(entity.getId())) return 0; + + // Check attempted breaks + if (attemptedBreaks.get(entity.getId()) > breakAttempts.get()) return 0; + + // Check crystal age + if (checkCrystalAge && entity.age < ticksExisted.get()) return 0; + + // Check range + if (isOutOfRange(entity.getPos(), entity.getBlockPos(), false)) return 0; + + // Check damage to self and anti suicide + blockPos.set(entity.getBlockPos()).move(0, -1, 0); + float selfDamage = DamageUtils.crystalDamage(mc.player, entity.getPos(), predictMovement.get(), blockPos); + if (selfDamage > maxDamage.get() || (antiSuicide.get() && selfDamage >= EntityUtils.getTotalHealth(mc.player))) return 0; + + // Check damage to targets and face place + float damage = getDamageToTargets(entity.getPos(), blockPos, true, false); + boolean shouldFacePlace = shouldFacePlace(); + double minimumDamage = shouldFacePlace ? Math.min(minDamage.get(), 1.5d) : minDamage.get(); + + if (damage < minimumDamage) return 0f; + + return damage; + } + + private void doBreak(Entity crystal) { + // Anti weakness + if (antiWeakness.get()) { + StatusEffectInstance weakness = mc.player.getStatusEffect(StatusEffects.WEAKNESS); + StatusEffectInstance strength = mc.player.getStatusEffect(StatusEffects.STRENGTH); + + // Check for strength + if (weakness != null && (strength == null || strength.getAmplifier() <= weakness.getAmplifier())) { + // Check if the item in your hand is already valid + if (!isValidWeaknessItem(mc.player.getMainHandStack(), crystal)) { + // Find valid item to break with + if (!InvUtils.swap(InvUtils.findInHotbar(stack -> isValidWeaknessItem(stack, crystal)).slot(), false)) return; + + switchTimer = 1; + return; + } + } + } + + // Rotate and attack + boolean attacked = true; + + if (rotate.get()) { + double yaw = Rotations.getYaw(crystal); + double pitch = Rotations.getPitch(crystal, Target.Feet); + + if (doYawSteps(yaw, pitch)) { + setRotation(true, crystal.getPos(), 0, 0); + Rotations.rotate(yaw, pitch, 50, () -> attackCrystal(crystal)); + + breakTimer = breakDelay.get(); + } + else { + attacked = false; + } + } + else { + attackCrystal(crystal); + breakTimer = breakDelay.get(); + } + + if (attacked) { + // Update state + removed.add(crystal.getId()); + attemptedBreaks.put(crystal.getId(), attemptedBreaks.get(crystal.getId()) + 1); + waitingToExplode.put(crystal.getId(), 0); + + // Break render + breakRenderPos.set(crystal.getBlockPos().down()); + breakRenderTimer = breakRenderTime.get(); + } + } + + private boolean isValidWeaknessItem(ItemStack itemStack, Entity crystal) { + return DamageUtils.getAttackDamage(mc.player, (LivingEntity) crystal, itemStack) > 0; + } + + private void attackCrystal(Entity entity) { + // Attack + mc.player.networkHandler.sendPacket(PlayerInteractEntityC2SPacket.attack(entity, mc.player.isSneaking())); + + Hand hand = InvUtils.findInHotbar(Items.END_CRYSTAL).getHand(); + if (hand == null) hand = Hand.MAIN_HAND; + + if (swingMode.get().client()) mc.player.swingHand(hand); + if (swingMode.get().packet()) mc.getNetworkHandler().sendPacket(new HandSwingC2SPacket(hand)); + + attacks++; + } + + @EventHandler + private void onPacketSend(PacketEvent.Send event) { + if (event.packet instanceof UpdateSelectedSlotC2SPacket) { + switchTimer = switchDelay.get(); + } + } + + // Place + + private void doPlace() { + if (!doPlace.get() || placeTimer > 0) return; + if (shouldPause(PauseMode.Place)) return; + + // Return if there are no crystals in hotbar or offhand + if (!InvUtils.testInHotbar(Items.END_CRYSTAL)) return; + + // Return if there are no crystals in either hand and auto switch mode is none + if (autoSwitch.get() != AutoSwitchMode.None) { + if (noGapSwitch.get() && autoSwitch.get() == AutoSwitchMode.Normal && offItem != Items.END_CRYSTAL) { + if (mainItem == Items.ENCHANTED_GOLDEN_APPLE + || offItem == Items.ENCHANTED_GOLDEN_APPLE + || mainItem == Items.GOLDEN_APPLE + || offItem == Items.GOLDEN_APPLE) return; + } + if (noBowSwitch.get() && (mainItem == Items.BOW || offItem == Items.BOW)) return; + } else if (mainItem != Items.END_CRYSTAL && offItem != Items.END_CRYSTAL) return; + + // Check for multiplace + for (Entity entity : mc.world.getEntities()) { + if (getBreakDamage(entity, false) > 0) return; + } + + // Setup variables + AtomicDouble bestDamage = new AtomicDouble(0); + AtomicReference bestBlockPos = new AtomicReference<>(new BlockPos.Mutable()); + AtomicBoolean isSupport = new AtomicBoolean(support.get() != SupportMode.Disabled); + + // Find best position to place the crystal on + BlockIterator.register((int) Math.ceil(placeRange.get()), (int) Math.ceil(placeRange.get()), (bp, blockState) -> { + // Check if its bedrock or obsidian and return if isSupport is false + boolean hasBlock = blockState.isOf(Blocks.BEDROCK) || blockState.isOf(Blocks.OBSIDIAN); + if (!hasBlock && (!isSupport.get() || !blockState.isReplaceable())) return; + + // Check if there is air on top + blockPos.set(bp.getX(), bp.getY() + 1, bp.getZ()); + if (!mc.world.getBlockState(blockPos).isAir()) return; + + if (placement112.get()) { + blockPos.move(0, 1, 0); + if (!mc.world.getBlockState(blockPos).isAir()) return; + } + + // Check range + ((IVec3d) vec3d).meteor$set(bp.getX() + 0.5, bp.getY() + 1, bp.getZ() + 0.5); + blockPos.set(bp).move(0, 1, 0); + if (isOutOfRange(vec3d, blockPos, true)) return; + + // Check damage to self and anti suicide + float selfDamage = DamageUtils.crystalDamage(mc.player, vec3d, predictMovement.get(), bp); + if (selfDamage > maxDamage.get() || (antiSuicide.get() && selfDamage >= EntityUtils.getTotalHealth(mc.player))) return; + + // Check damage to targets and face place + float damage = getDamageToTargets(vec3d, bp, false, !hasBlock && support.get() == SupportMode.Fast); + + boolean shouldFacePlace = shouldFacePlace(); + double minimumDamage = Math.min(minDamage.get(), shouldFacePlace ? 1.5 : minDamage.get()); + + if (damage < minimumDamage) return; + + // Check if it can be placed + double x = bp.getX(); + double y = bp.getY() + 1; + double z = bp.getZ(); + ((IBox) box).meteor$set(x, y, z, x + 1, y + (placement112.get() ? 1 : 2), z + 1); + + if (intersectsWithEntities(box)) return; + + // Compare damage + if (damage > bestDamage.get() || (isSupport.get() && hasBlock)) { + bestDamage.set(damage); + bestBlockPos.get().set(bp); + } + + if (hasBlock) isSupport.set(false); + }); + + // Place the crystal + BlockIterator.after(() -> { + if (bestDamage.get() == 0) return; + + BlockHitResult result = getPlaceInfo(bestBlockPos.get()); + + ((IVec3d) vec3d).meteor$set( + result.getBlockPos().getX() + 0.5 + result.getSide().getVector().getX() * 1.0 / 2.0, + result.getBlockPos().getY() + 0.5 + result.getSide().getVector().getY() * 1.0 / 2.0, + result.getBlockPos().getZ() + 0.5 + result.getSide().getVector().getZ() * 1.0 / 2.0 + ); + + if (rotate.get()) { + double yaw = Rotations.getYaw(vec3d); + double pitch = Rotations.getPitch(vec3d); + + if (yawStepMode.get() == YawStepMode.Break || doYawSteps(yaw, pitch)) { + setRotation(true, vec3d, 0, 0); + Rotations.rotate(yaw, pitch, 50, () -> placeCrystal(result, bestDamage.get(), isSupport.get() ? bestBlockPos.get() : null)); + + placeTimer += placeDelay.get(); + } + } + else { + placeCrystal(result, bestDamage.get(), isSupport.get() ? bestBlockPos.get() : null); + placeTimer += placeDelay.get(); + } + }); + } + + private BlockHitResult getPlaceInfo(BlockPos blockPos) { + ((IVec3d) vec3d).meteor$set(mc.player.getX(), mc.player.getY() + mc.player.getEyeHeight(mc.player.getPose()), mc.player.getZ()); + + for (Direction side : Direction.values()) { + ((IVec3d) vec3dRayTraceEnd).meteor$set( + blockPos.getX() + 0.5 + side.getVector().getX() * 0.5, + blockPos.getY() + 0.5 + side.getVector().getY() * 0.5, + blockPos.getZ() + 0.5 + side.getVector().getZ() * 0.5 + ); + + ((IRaycastContext) raycastContext).meteor$set(vec3d, vec3dRayTraceEnd, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player); + BlockHitResult result = mc.world.raycast(raycastContext); + + if (result != null && result.getType() == HitResult.Type.BLOCK && result.getBlockPos().equals(blockPos)) { + return result; + } + } + + Direction side = blockPos.getY() > vec3d.y ? Direction.DOWN : Direction.UP; + return new BlockHitResult(vec3d, side, blockPos, false); + } + + private void placeCrystal(BlockHitResult result, double damage, BlockPos supportBlock) { + // Switch + Item targetItem = supportBlock == null ? Items.END_CRYSTAL : Items.OBSIDIAN; + + FindItemResult item = InvUtils.findInHotbar(targetItem); + if (!item.found()) return; + + // int prevSlot = mc.player.getInventory().getSelectedSlot(); + int prevSlot = InvUtils.previousSlot; + + if (autoSwitch.get() != AutoSwitchMode.None && !item.isOffhand()) InvUtils.swap(item.slot(), false); + + Hand hand = item.getHand(); + if (hand == null) return; + + // Place + if (supportBlock == null) { + // Place crystal + mc.player.networkHandler.sendPacket(new PlayerInteractBlockC2SPacket(hand, result, 0)); + + if (swingMode.get().client()) mc.player.swingHand(hand); + if (swingMode.get().packet()) mc.getNetworkHandler().sendPacket(new HandSwingC2SPacket(hand)); + + placing = true; + placingTimer = 4; + kaTimer = 8; + placingCrystalBlockPos.set(result.getBlockPos()).move(0, 1, 0); + + placeRenderPos.set(result.getBlockPos()); + renderDamage = damage; + + if (renderMode.get() == RenderMode.Normal) { + placeRenderTimer = placeRenderTime.get(); + } else { + placeRenderTimer = renderTime.get(); + if (renderMode.get() == RenderMode.Fading) { + RenderUtils.renderTickingBlock( + placeRenderPos, sideColor.get(), + lineColor.get(), shapeMode.get(), + 0, renderTime.get(), true, + false + ); + } + } + } + else { + // Place support block + BlockUtils.place(supportBlock, item, false, 0, swingMode.get().client(), true, false); + placeTimer += supportDelay.get(); + + if (supportDelay.get() == 0) placeCrystal(result, damage, null); + } + + // Switch back + if (autoSwitch.get() == AutoSwitchMode.Silent) InvUtils.swap(prevSlot, false); + } + + // Yaw steps + + @EventHandler + private void onPacketSent(PacketEvent.Sent event) { + if (event.packet instanceof PlayerMoveC2SPacket) { + serverYaw = ((PlayerMoveC2SPacket) event.packet).getYaw((float) serverYaw); + } + } + + public boolean doYawSteps(double targetYaw, double targetPitch) { + targetYaw = MathHelper.wrapDegrees(targetYaw) + 180; + double serverYaw = MathHelper.wrapDegrees(this.serverYaw) + 180; + + if (distanceBetweenAngles(serverYaw, targetYaw) <= yawSteps.get()) return true; + + double delta = Math.abs(targetYaw - serverYaw); + double yaw = this.serverYaw; + + if (serverYaw < targetYaw) { + if (delta < 180) yaw += yawSteps.get(); + else yaw -= yawSteps.get(); + } + else { + if (delta < 180) yaw -= yawSteps.get(); + else yaw += yawSteps.get(); + } + + setRotation(false, null, yaw, targetPitch); + Rotations.rotate(yaw, targetPitch, -100, null); // Priority -100 so it sends the packet as the last one, im pretty sure it doesn't matte but idc + return false; + } + + private static double distanceBetweenAngles(double alpha, double beta) { + double phi = Math.abs(beta - alpha) % 360; + return phi > 180 ? 360 - phi : phi; + } + + // Face place + + private boolean shouldFacePlace() { + if (!facePlace.get()) return false; + + if (forceFacePlace.get().isPressed()) return true; + + // Checks if the provided crystal position should face place to any target + for (LivingEntity target : targets) { + if (EntityUtils.getTotalHealth(target) <= facePlaceHealth.get()) return true; + + for (EquipmentSlot slot : AttributeModifierSlot.ARMOR) { + ItemStack itemStack = target.getEquippedStack(slot); + + if (itemStack == null || itemStack.isEmpty()) { + if (facePlaceArmor.get()) return true; + } else { + if ((double) (itemStack.getMaxDamage() - itemStack.getDamage()) / itemStack.getMaxDamage() * 100 <= facePlaceDurability.get()) return true; + } + } + } + + return false; + } + + // Others + + private boolean shouldPause(PauseMode process) { + if (mc.player.isUsingItem() || mc.options.useKey.isPressed()) { + if (pauseOnUse.get().equals(process)) return true; + } + + if (pauseOnLag.get() && TickRate.INSTANCE.getTimeSinceLastTick() >= 1.0f) return true; + for (Module module : pauseModules.get()) if (module.isActive()) return true; + if (pauseOnMine.get().equals(process) && mc.interactionManager.isBreakingBlock()) return true; + return (EntityUtils.getTotalHealth(mc.player) <= pauseHealth.get()); + } + + private boolean isOutOfRange(Vec3d vec3d, BlockPos blockPos, boolean place) { + ((IRaycastContext) raycastContext).meteor$set(playerEyePos, vec3d, RaycastContext.ShapeType.COLLIDER, RaycastContext.FluidHandling.NONE, mc.player); + + BlockHitResult result = mc.world.raycast(raycastContext); + + if (result == null || !result.getBlockPos().equals(blockPos)) // Is behind wall + return !PlayerUtils.isWithin(vec3d, (place ? placeWallsRange : breakWallsRange).get()); + return !PlayerUtils.isWithin(vec3d, (place ? placeRange : breakRange).get()); + } + + private LivingEntity getNearestTarget() { + LivingEntity nearestTarget = null; + double nearestDistance = Double.MAX_VALUE; + + for (LivingEntity target : targets) { + double distance = PlayerUtils.squaredDistanceTo(target); + + if (distance < nearestDistance) { + nearestTarget = target; + nearestDistance = distance; + } + } + + return nearestTarget; + } + + private float getDamageToTargets(Vec3d vec3d, BlockPos obsidianPos, boolean breaking, boolean fast) { + float damage = 0; + + if (fast) { + LivingEntity target = getNearestTarget(); + if (!(smartDelay.get() && breaking && target.hurtTime > 0)) damage = DamageUtils.crystalDamage(target, vec3d, predictMovement.get(), obsidianPos); + } + else { + for (LivingEntity target : targets) { + if (smartDelay.get() && breaking && target.hurtTime > 0) continue; + + float dmg = DamageUtils.crystalDamage(target, vec3d, predictMovement.get(), obsidianPos); + + // Update best target + if (dmg > bestTargetDamage) { + bestTarget = target; + bestTargetDamage = dmg; + bestTargetTimer = 10; + } + + damage += dmg; + } + } + + return damage; + } + + @Override + public String getInfoString() { + return bestTarget != null && bestTargetTimer > 0 ? EntityUtils.getName(bestTarget) : null; + } + + private void findTargets() { + targets.clear(); + + // Living Entities + for (Entity entity : mc.world.getEntities()) { + // Ignore non-living + if (!(entity instanceof LivingEntity livingEntity)) continue; + + // Player + if (livingEntity instanceof PlayerEntity player) { + if (player.getAbilities().creativeMode || livingEntity == mc.player) continue; + if (!player.isAlive() || !Friends.get().shouldAttack(player)) continue; + //TODO: prioritize enemies + + if (ignoreNakeds.get()) { + if (player.getOffHandStack().isEmpty() + && player.getMainHandStack().isEmpty() + && player.getEquippedStack(EquipmentSlot.FEET).isEmpty() + && player.getEquippedStack(EquipmentSlot.LEGS).isEmpty() + && player.getEquippedStack(EquipmentSlot.CHEST).isEmpty() + && player.getEquippedStack(EquipmentSlot.HEAD).isEmpty() + ) continue; + } + } + + // Animals, water animals, monsters, bats, misc + if (!(entities.get().contains(livingEntity.getType()))) continue; + + // Close enough to damage + if (livingEntity.squaredDistanceTo(mc.player) > targetRange.get() * targetRange.get()) continue; + + targets.add(livingEntity); + } + } + + private boolean intersectsWithEntities(Box box) { + return EntityUtils.intersectsWithEntity(box, entity -> !entity.isSpectator() && !removed.contains(entity.getId())); + } + + // Rendering + + @EventHandler + private void onRender(Render3DEvent event) { + if (renderMode.get() == RenderMode.None) return; + + switch (renderMode.get()) { + case Normal -> { + if (renderPlace.get() && placeRenderTimer > 0) { + event.renderer.box(placeRenderPos, sideColor.get(), lineColor.get(), shapeMode.get(), 0); + } + if (renderBreak.get() && breakRenderTimer > 0) { + event.renderer.box(breakRenderPos, sideColor.get(), lineColor.get(), shapeMode.get(), 0); + } + } + + case Smooth -> { + if (placeRenderTimer <= 0) return; + + if (renderBoxOne == null) renderBoxOne = new Box(placeRenderPos); + if (renderBoxTwo == null) renderBoxTwo = new Box(placeRenderPos); + else ((IBox) renderBoxTwo).meteor$set(placeRenderPos); + + double offsetX = (renderBoxTwo.minX - renderBoxOne.minX) / smoothness.get(); + double offsetY = (renderBoxTwo.minY - renderBoxOne.minY) / smoothness.get(); + double offsetZ = (renderBoxTwo.minZ - renderBoxOne.minZ) / smoothness.get(); + + ((IBox) renderBoxOne).meteor$set( + renderBoxOne.minX + offsetX, + renderBoxOne.minY + offsetY, + renderBoxOne.minZ + offsetZ, + renderBoxOne.maxX + offsetX, + renderBoxOne.maxY + offsetY, + renderBoxOne.maxZ + offsetZ + ); + + event.renderer.box(renderBoxOne, sideColor.get(), lineColor.get(), shapeMode.get(), 0); + } + + case Gradient -> { + if (placeRenderTimer <= 0) return; + + Color bottom = new Color(0, 0, 0, 0); + + int x = placeRenderPos.getX(); + int y = placeRenderPos.getY() + 1; + int z = placeRenderPos.getZ(); + + if (shapeMode.get().sides()) { + event.renderer.quadHorizontal(x, y, z, x + 1, z + 1, sideColor.get()); + event.renderer.gradientQuadVertical(x, y, z, x + 1, y - height.get(), z, bottom, sideColor.get()); + event.renderer.gradientQuadVertical(x, y, z, x, y - height.get(), z + 1, bottom, sideColor.get()); + event.renderer.gradientQuadVertical(x + 1, y, z, x + 1, y - height.get(), z + 1, bottom, sideColor.get()); + event.renderer.gradientQuadVertical(x, y, z + 1, x + 1, y - height.get(), z + 1, bottom, sideColor.get()); + } + + if (shapeMode.get().lines()) { + event.renderer.line(x, y, z, x + 1, y, z, lineColor.get()); + event.renderer.line(x, y, z, x, y, z + 1, lineColor.get()); + event.renderer.line(x + 1, y, z, x + 1, y, z + 1, lineColor.get()); + event.renderer.line(x, y, z + 1, x + 1, y, z + 1, lineColor.get()); + + event.renderer.line(x, y, z, x, y - height.get(), z, lineColor.get(), bottom); + event.renderer.line(x + 1, y, z, x + 1, y - height.get(), z, lineColor.get(), bottom); + event.renderer.line(x, y, z + 1, x, y - height.get(), z + 1, lineColor.get(), bottom); + event.renderer.line(x + 1, y, z + 1, x + 1, y - height.get(), z + 1, lineColor.get(), bottom); + } + } + } + } + + @EventHandler + private void onRender2D(Render2DEvent event) { + if (renderMode.get() == RenderMode.None || !renderDamageText.get()) return; + if (placeRenderTimer <= 0 && breakRenderTimer <= 0) return; + + if (renderMode.get() == RenderMode.Smooth) { + if (renderBoxOne == null) return; + vec3.set(renderBoxOne.minX + 0.5, renderBoxOne.minY + 0.5, renderBoxOne.minZ + 0.5); + } else vec3.set(placeRenderPos.getX() + 0.5, placeRenderPos.getY() + 0.5, placeRenderPos.getZ() + 0.5); + + if (NametagUtils.to2D(vec3, damageTextScale.get())) { + NametagUtils.begin(vec3); + TextRenderer.get().begin(1, false, true); + + String text = String.format("%.1f", renderDamage); + double w = TextRenderer.get().getWidth(text) / 2; + TextRenderer.get().render(text, -w, 0, damageColor.get(), true); + + TextRenderer.get().end(); + NametagUtils.end(); + } + } + + public enum YawStepMode { + Break, + All, + } + + public enum AutoSwitchMode { + Normal, + Silent, + None + } + + public enum SupportMode { + Disabled, + Accurate, + Fast + } + + public enum PauseMode { + Both, + Place, + Break, + None; + + public boolean equals(PauseMode process) { + return this == process || this == PauseMode.Both; + } + } + + public enum SwingMode { + Both, + Packet, + Client, + None; + + public boolean packet() { + return this == Packet || this == Both; + } + + public boolean client() { + return this == Client || this == Both; + } + } + + public enum RenderMode { + Normal, + Smooth, + Fading, + Gradient, + None + } + +} diff --git a/src/main/resources/assets/genyo/icon.png b/src/main/resources/assets/genyo/icon.png index 3fb2e7f3399807de6c34adbf0fdd41afa2ff438c..e5021a2e9f058a227b468ceb267aa16f3bf689ea 100644 GIT binary patch literal 3351 zcmZ`+`9GBH7k*IL#_mN-W=s^)*tb#kednF5VK5_2!XW!D>uVXZWKEXWQubv?Su08Q zP)1~HOvt{5zR&vye4o#`pYy~0`P}z&&biKYt|!slRF8#;p9uf}76W~4OVF$Tw-_#g z@9O)6InXhB>)ZMQ0P^a8izcvK%^v_D0|wd}=)i&vy9dVhD*}HCCng4qV{5;8W9=0& znKj9@S_%cvT0bS5klt28Y_s{exQq>q<8sX28o4dz-26(})cbGS)+w{QPmZ<3Rh)#9X$ z0=~5oV(@spe#OK<7{CrJDy8o1?owyledT0iG^638csMtcML>Y!oAZ;ky)Uk5W6!nX zE32!M=E4pgd{BkLNiO5A8a{{_jyUIpC8glybiD*h(AQ&F_)(N#_>r@vD7Oz;dnEg& z{pwPh+Q04X?U^c@`@z(+!}*HWuU}te?v{dxWf_X!xKV19gG?Wx7^OzqP|D+Rw$+uD zMC+Ytr-<^rygXcCPO`GkGQ(?lV}6G4#)29?$&W=f;NJWpTGChC*$7M#P9wc)}O|2ZDBlviE}OTZw_P^@gmhj+mgz2+WI;@=%?kkgBbSi9z*Wzyv4=1S!nW4?aAtC+wL zA^5c{U~+j`SoL&EtGT)P1M>$dh@HK?w3Jlj$;nB%q!xHcVPWCZf`YfdzI8PCQijW{ zGI6$0lpn*jCt}K*8IgwNy{T7Ju+Lkdd~q~`jYnXx(rRjH$Hzf|Zydou!7AK+<;Q4U z=NPM5G4X~6a*2yoGa@NveB9Ee#!3nj^Xr#q;H@H&>m(ZqCEp(q5Ledgt1cK@9>a3Z zhYufq4+{T!0PWYPn|8(H4Xvt5L=l{cA5@BPwxW$qO-{ZY-w0&Gj7G3=>}q&I4u8eI zbBVI6iJPE4o?g4?z1ard@Mvvnp*xB$aIJ<^?=|02rr zsA?!5*q>X!&zKi=_pZFd%FuXq9$&+`xxKIIS=B4I9BXjxU!^>Y0I?>@nFuln)Wq0$ z^vf4M6BCp4={1x4!%j@9&(dlgI&`m_6_phfK*!hiu~K}M_4P#4XR0PcLqmQ$%L5`h z0{sN^ojW?l_wHT4{pWOdl}e2gO=7$%(I+)Z^$Xk?xV}AZBq^k*s7S>$+Y$YLeCr61 zmX@Z8bFL>W=_ZsU)ODUPQAVEi&(7ZM?Hni6)YZ}dTTwyHvUYq9vX#gk!9Jd=e z^n&W9rmQ+2rwEq35;dwq$yD9B=9j!uyr$RUA5ZS1`;RoGo5Z(Mx5 zw31T7+??ay-X6xo10tA4pOI=i>~??ncE~}uC&~5j*SCn-i#FLhj*fz+g{att1!q5h ze@*tsIQq=Dv2cd1;5Se6@_GwZ0*b9(^bnwas4IKHw?Uh#b7G6>iA+w0tnLScA96hA zE=Lq@AECsMH{O5#%pF)nKeEdQgT)W7ME5Ugz}bn`s4=9&$DnMSvrMkJz5PF@r=e01 z-%Xh^%PMmVi>R3yJ8&eGc6F(VahCYLEE5S;g#noGa6wmB*BxndQSO}%%c{%(qVUrM zeX9pxUZde)2|s)lI}og&9m|-Jh0uY$S6G-rDGFijPlLtlmPW}{K`glM*^|^qiGF| zjGkoOskU;L*Uy5Q85xy=y&1eeX-%D~vFB#Ez-X(`n4Yce<-Opul1GUmj6^sC z?X0IF$flz+GfAnbtPlt!k`mPR%~Sd4rvLMk7t0b;lBgqT$W^B>lGl7{ykIbcUYeke zfdON(?oy-Tco_o`6dtGHY9Lg?|C|Nv9Uk^Aco$bx(3h5$`iyBL&2kDgaNI(n^dewn zh1Rq^{XESVlP+shHT8BiqBn2q5D3!#>tCYw*QT#KB-(M%a3<)RT7Y=>_4VZw5Qv$e zYCAc>F45CVqfkk?xtDD#!65~j@{kT?+eWiw;#xmp)LqVoMAdiKkDWMh>p@f>XxL%}q*0 zg*mN11{5tADN$>8;V}4F{-C>@%kGaMa4doLrQVsY+3x1}_&B!eY@Wx#Qdb?Je?#I5 zV--}SN^gKb4PYE+CAOma3E!1i@h!no7()@OtjGwu^UVl^@3Y7(e|J2-7o3Z4;5R2H zC!beU-Irgt50khS%Vn_i^XE?yoV%8mR%73pD^ZSSY*%jD?SJ7w#T||B=UfV0@uhcmPF=l7DC`XJcI#| z&;%9P08r^H`=NM=Y?15!AwL<3$Q!FCuZ_wWdbam14djiT z0)>1N!Re*#4@=i%^*%BXZPG;G{;@Q~zJ=nZdn4~JZ~CEdF=R5Cm;JjRDluU>oSscE z**AN2PE$@!?t`zjwe{dUi9{L!a^A{;yuAE}p`nWa8jS`3U0q#bQBi7+Q}|_I3zS{7Kd_6crN+j_(b3UJa1<1%1h4`iIWYq} zh7o&XdLY06z|YU`gGy=iLlg)fTicfK1DCVjMQJM+6=Th zGM+b(dh}pn=y1|k52c9n)9O#YUGT=KOE2Yran=9l&gr}^{!Bi++P^grrNcd HnCSljuMkd2 delta 2124 zcmV-S2($N>8rcw#B!2;OQb$4nuFf3k00004XF*Lt006O%3;baP00009a7bBm000id z000id0mpBsWB>pM?ny*JRCr$Pnt4=Ibri?%@4b1mFu;J8OIb!LGJuqIuw3f6pjMWd zttYcxNe^})wK5YkJ(i_G>B-W}7V4B%ltn3m;F3$0m58Fbbbl%g7}=y*-`0JP-%O6x zFas0LIla$6Gr#Y9^O)cFcklh(HxJOz(9qD((9qD((9qD(2+R!^-vjTA*b_yEZSvOe zok5>_t|0WaO*V`@mc}vqd_tHMQ4;3WI)7dB;MQRxJ?zKFqYuTKbmm-!u$hu9zUdMj z^CuQ3)ziZfMSoBRyganxvBcOeOBh0QR02tszUL)R_8lcD+gzfPssQhg+-He5oWBDn zpGqZ=L2f|P=GVEZUwfc@h(P6tfT6DeIof>sitV*EI-AQy75pG!1{zpn`6pwJtScOI zxHpyI?k!g|xA09vMOk0;G$M;gUHk(^(tl|6#0Vj%2$+%jbpavlB;|cK zlL?aJ;=ruq)ME-bQ72A#shvN)cBf4i!DDHQZ zO6QEA49H6T`c(|+X>^FIPvDa1Xy_Yj0gm}Ah|q}N1c{$h)wJ)uS-U67ik1>T2$o#+ z;bWTK1ZBWIi65{Q{e@E)qFadJd>)lS&#=(n zVu6d$j59BUg>RQfa%bPXsqZ&bg0;hU>drS_@Cc^D0wpD=te94drp>LkA77ifeWXO? zP9rD-yiBofj5n~+^D!Ex<41it5X#3yDGb#$KmN+o!eDhLP zxCM8B#Vvee-d&}at3^@av$4lg^^86b&CH;Zf{c+f_oj^r&(X0T*Yvm%w%2??N8zDe z27f3R*cf=&S~L#RVi^IZKb3*S`j8M4i}fK^eeXpE=@>8Zvr4N!`ZT{{wyO2B41m1B z8*aw>uoMWfpi#Lt*U8oQmk;*qFVw%llXVW3o`$7N%i{AU#@tZ9_<+IHo(h$ z{Xf!2bKSGhh(IN=py#oG_M)9oI*?_!d<@rXsie}&Y{nfUPK^v%mJSQDFf)7CO+`nW zeSx4-IOa%CBWqfW6TcUSZ8mCHW9pUGyun?!dU9EM$X#ZK445%sC$@&F=d?*%uH>n#@-C)97elukmeDbWWxRZpO}EV%2I5v`%t;vU|JNqMdz$riW84hDSseA-3$C1 zvMl@J7bkfg#~Alx*O-U(KrM!A4vllJI52FXM{*>gLGPoac86ZNo07=HgxMw7E*FMl z@(S2r+=6$al?9_tV4u-89WtPWuen;1g-pytTdP7iG$LEiMjy#a-H~~3;ySe$zE(Nv zw-pD5P7);dHE6_P^;8uC-+$OnjjC*H1dkM+CJ=8*;1`Evw7Fpzl>!o$U0`Z*ah#rs zQttn=6cebdg!_*;>1<4kaw_@J-DD+q_Fb#aT)C%6#J0M3bWFRxlz_2ibBoZ-w+0y+ zU68XQVX`_1K!+m0%c_H8nlRKK<0WUBEQ?=J87IPA#xbTcOpEo?Qh&BwLgjyi#|Tg& zVSCN*aO#ZP?zT{-TknzJxLxo~J`}=YfR~k(Bdhk>-o8PQJ>xJfe4&n!aT^+O5RF(k zHF=YNXLJ@VJP&(pb@1&e8`y=wyIKn_`*FL7D=*=SQ!zxsYJkG-+EwuCfos3C^R_gs z4>QpS+T9To8u2u?(0>oLjssKcbiy`_hN`9}5YDO(Zk+8e4iT!IB1TR-XHE&b0bbs$ z8t=ihc*!lcB%%?kQS$cpL8rJR%W$maG?b$ezuN7X=Q7l|BshVq?!aOf4*oL(ykLE( zLnEeQeMrX+a2u6F!Yzuhzo8!XH`<|z5ARO~|G5EPa3}b_+JC-pxJPspP$^`>v*!ME zngI%*oXC=2KbR3wKaY2+0g;Gi0Db-6a!w7v9zkiBf2PB*g4aDk-v;EI8c^q~k{v=r zGWH4c@GJWssB{F}YAbokH8yuodM=d$5|*2xaDev;y;x#+4!cF=3DiG+uO8+uVCIZ; z0C}IroGCieyFsnR;24)bIeEf?6f+!2C+@d{q&aMF= zZ?O?)fWqy4Rx{m9Ns}3(TTFmlK;^#~fGb{#;hyvOPOJY9iy;t^26&lb{VK-5#?D~~ zlY?K?=rurj#vn-i>>o}Q6&4)Mrf0X0h&I3rrp2WU;YD8TY3`a~;`EE1LUaDy-2;73 znf@0TSqsca`!eGH Date: Sun, 6 Jul 2025 22:01:26 +0200 Subject: [PATCH 2/4] angel hulkenberg --- .../com/genyo/addon/events/TotemPopEvent.java | 4 + .../genyo/addon/managers/CombatManager.java | 4 + .../com/genyo/addon/managers/Managers.java | 4 + .../java/com/genyo/addon/mixin/IEntity.java | 4 + .../addon/modules/AngelSexHulkenberg.java | 6 + .../com/genyo/addon/modules/CoopCrystal.java | 1595 ----------------- .../{GenyoKristaj.java => TescoCrystal.java} | 28 +- .../genyo/addon/render/Render2DEngine.java | 4 + .../genyo/addon/render/Render3DEngine.java | 4 + .../java/com/genyo/addon/utils/MathUtil.java | 4 + src/main/resources/genyo.accesswidener | 0 11 files changed, 50 insertions(+), 1607 deletions(-) create mode 100644 src/main/java/com/genyo/addon/events/TotemPopEvent.java create mode 100644 src/main/java/com/genyo/addon/managers/CombatManager.java create mode 100644 src/main/java/com/genyo/addon/managers/Managers.java create mode 100644 src/main/java/com/genyo/addon/mixin/IEntity.java create mode 100644 src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java delete mode 100644 src/main/java/com/genyo/addon/modules/CoopCrystal.java rename src/main/java/com/genyo/addon/modules/{GenyoKristaj.java => TescoCrystal.java} (98%) create mode 100644 src/main/java/com/genyo/addon/render/Render2DEngine.java create mode 100644 src/main/java/com/genyo/addon/render/Render3DEngine.java create mode 100644 src/main/java/com/genyo/addon/utils/MathUtil.java create mode 100644 src/main/resources/genyo.accesswidener diff --git a/src/main/java/com/genyo/addon/events/TotemPopEvent.java b/src/main/java/com/genyo/addon/events/TotemPopEvent.java new file mode 100644 index 0000000..873ab64 --- /dev/null +++ b/src/main/java/com/genyo/addon/events/TotemPopEvent.java @@ -0,0 +1,4 @@ +package com.genyo.addon.events; + +public class TotemPopEvent { +} diff --git a/src/main/java/com/genyo/addon/managers/CombatManager.java b/src/main/java/com/genyo/addon/managers/CombatManager.java new file mode 100644 index 0000000..a2a6578 --- /dev/null +++ b/src/main/java/com/genyo/addon/managers/CombatManager.java @@ -0,0 +1,4 @@ +package com.genyo.addon.managers; + +public class CombatManager { +} diff --git a/src/main/java/com/genyo/addon/managers/Managers.java b/src/main/java/com/genyo/addon/managers/Managers.java new file mode 100644 index 0000000..9dce698 --- /dev/null +++ b/src/main/java/com/genyo/addon/managers/Managers.java @@ -0,0 +1,4 @@ +package com.genyo.addon.managers; + +public class Managers { +} diff --git a/src/main/java/com/genyo/addon/mixin/IEntity.java b/src/main/java/com/genyo/addon/mixin/IEntity.java new file mode 100644 index 0000000..b19c0de --- /dev/null +++ b/src/main/java/com/genyo/addon/mixin/IEntity.java @@ -0,0 +1,4 @@ +package com.genyo.addon.mixin; + +public interface IEntity { +} diff --git a/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java b/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java new file mode 100644 index 0000000..7631b86 --- /dev/null +++ b/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java @@ -0,0 +1,6 @@ +package com.genyo.addon.modules; + +import meteordevelopment.meteorclient.systems.modules.Module; + +public class AngelSexHulkenberg extends Module { +} diff --git a/src/main/java/com/genyo/addon/modules/CoopCrystal.java b/src/main/java/com/genyo/addon/modules/CoopCrystal.java deleted file mode 100644 index 998c82f..0000000 --- a/src/main/java/com/genyo/addon/modules/CoopCrystal.java +++ /dev/null @@ -1,1595 +0,0 @@ -package com.genyo.addon.modules; - -import com.genyo.addon.GenyoAddon; -import kassuk.addon.blackout.BlackOut; -import kassuk.addon.blackout.BlackOutModule; -import kassuk.addon.blackout.enums.RotationType; -import kassuk.addon.blackout.enums.SwingHand; -import kassuk.addon.blackout.enums.SwingState; -import kassuk.addon.blackout.enums.SwingType; -import kassuk.addon.blackout.managers.Managers; -import kassuk.addon.blackout.mixins.IInteractEntityC2SPacket; -import kassuk.addon.blackout.timers.TimerList; -import kassuk.addon.blackout.utils.BOInvUtils; -import kassuk.addon.blackout.utils.ExtrapolationUtils; -import kassuk.addon.blackout.utils.OLEPOSSUtils; -import kassuk.addon.blackout.utils.SettingUtils; -import kassuk.addon.blackout.utils.meteor.BODamageUtils; -import kassuk.addon.blackout.utils.meteor.BOEntityUtils; -import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; -import meteordevelopment.meteorclient.events.packets.PacketEvent; -import meteordevelopment.meteorclient.events.render.Render3DEvent; -import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.renderer.ShapeMode; -import meteordevelopment.meteorclient.settings.*; -import meteordevelopment.meteorclient.systems.friends.Friends; -import meteordevelopment.meteorclient.systems.modules.Module; -import meteordevelopment.meteorclient.systems.modules.Modules; -import meteordevelopment.meteorclient.utils.player.InvUtils; -import meteordevelopment.meteorclient.utils.render.color.Color; -import meteordevelopment.meteorclient.utils.render.color.SettingColor; -import meteordevelopment.orbit.EventHandler; -import meteordevelopment.orbit.EventPriority; -import net.minecraft.block.AirBlock; -import net.minecraft.block.Blocks; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.entity.Entity; -import net.minecraft.entity.decoration.EndCrystalEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.Items; -import net.minecraft.network.packet.c2s.play.PlayerInteractBlockC2SPacket; -import net.minecraft.network.packet.c2s.play.PlayerInteractEntityC2SPacket; -import net.minecraft.network.packet.c2s.play.UpdateSelectedSlotC2SPacket; -import net.minecraft.util.Hand; -import net.minecraft.util.math.*; - -import java.util.*; -import java.util.function.Predicate; - -public class CoopCrystal extends Module { - public CoopCrystal() { - super(GenyoAddon.GENYO, "Coop Crystal", "Tehát."); - } - - private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final SettingGroup sgPlace = settings.createGroup("Place"); - private final SettingGroup sgExplode = settings.createGroup("Explode"); - private final SettingGroup sgSwitch = settings.createGroup("Switch"); - private final SettingGroup sgDamage = settings.createGroup("Damage"); - private final SettingGroup sgID = settings.createGroup("ID Predict"); - private final SettingGroup sgExtrapolation = settings.createGroup("Extrapolation"); - private final SettingGroup sgRender = settings.createGroup("Render"); - private final SettingGroup sgCompatibility = settings.createGroup("Compatibility"); - private final SettingGroup sgDebug = settings.createGroup("Debug"); - - //--------------------General--------------------// - private final Setting place = sgGeneral.add(new BoolSetting.Builder() - .name("Place") - .description("Places crystals.") - .defaultValue(true) - .build() - ); - private final Setting explode = sgGeneral.add(new BoolSetting.Builder() - .name("Explode") - .description("Explodes crystals.") - .defaultValue(true) - .build() - ); - private final Setting pauseEat = sgGeneral.add(new BoolSetting.Builder() - .name("Pause Eat") - .description("Pauses while eating.") - .defaultValue(false) - .build() - ); - private final Setting performance = sgGeneral.add(new BoolSetting.Builder() - .name("Performance Mode") - .description("Doesn't calculate placements as often.") - .defaultValue(false) - .build() - ); - private final Setting smartRot = sgGeneral.add(new BoolSetting.Builder() - .name("Smart Rotations") - .description("Looks at the top of placement block to make the ca faster.") - .defaultValue(true) - .build() - ); - private final Setting ignoreTerrain = sgGeneral.add(new BoolSetting.Builder() - .name("Ignore Terrain") - .description("Spams trough terrain to kill your enemy.") - .defaultValue(true) - .build() - ); - - //--------------------Place--------------------// - private final Setting instantPlace = sgPlace.add(new BoolSetting.Builder() - .name("Instant Place") - .description("Ignores delay after crystal has disappeared.") - .defaultValue(true) - .build() - ); - private final Setting speedLimit = sgPlace.add(new DoubleSetting.Builder() - .name("Speed Limit") - .description("Maximum amount of place packets every second. 0 = no limit.") - .defaultValue(0) - .min(0) - .sliderRange(0, 20) - .visible(instantPlace::get) - .build() - ); - private final Setting placeSpeed = sgPlace.add(new DoubleSetting.Builder() - .name("Place Speed") - .description("How many times should the module place per second.") - .defaultValue(10) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting placeDelayMode = sgPlace.add(new EnumSetting.Builder() - .name("Place Delay Mode") - .description("Should we count the delay in seconds or ticks.") - .defaultValue(DelayMode.Seconds) - .build() - ); - private final Setting placeDelay = sgPlace.add(new DoubleSetting.Builder() - .name("Place Delay") - .description("How many seconds after attacking a crystal should we place.") - .defaultValue(0) - .min(0) - .sliderRange(0, 1) - .visible(() -> placeDelayMode.get() == DelayMode.Seconds) - .build() - ); - private final Setting placeDelayTicks = sgPlace.add(new IntSetting.Builder() - .name("Place Delay Ticks") - .description("How many ticks should the crystal exist before attacking.") - .defaultValue(0) - .min(0) - .sliderRange(0, 20) - .visible(() -> placeDelayMode.get() == DelayMode.Ticks) - .build() - ); - private final Setting slowDamage = sgPlace.add(new DoubleSetting.Builder() - .name("Slow Damage") - .description("Switches to slow speed when the target would take under this amount of damage.") - .defaultValue(3) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting slowSpeed = sgPlace.add(new DoubleSetting.Builder() - .name("Slow Speed") - .description("How many times should the module place per second when damage is under slow damage.") - .defaultValue(2) - .min(0) - .sliderRange(0, 20) - .build() - ); - - //--------------------Explode--------------------// - private final Setting onlyOwn = sgExplode.add(new BoolSetting.Builder() - .name("Only Own") - .description("Only attacks own crystals.") - .defaultValue(false) - .build() - ); - private final Setting inhibit = sgExplode.add(new BoolSetting.Builder() - .name("Inhibit") - .description("Stops targeting attacked crystals.") - .defaultValue(false) - .build() - ); - private final Setting existedMode = sgExplode.add(new EnumSetting.Builder() - .name("Existed Mode") - .description("Should crystal existed times be counted in seconds or ticks.") - .defaultValue(DelayMode.Seconds) - .build() - ); - private final Setting existed = sgExplode.add(new DoubleSetting.Builder() - .name("Existed") - .description("How many seconds should the crystal exist before attacking.") - .defaultValue(0) - .min(0) - .sliderRange(0, 1) - .visible(() -> existedMode.get() == DelayMode.Seconds) - .build() - ); - private final Setting existedTicks = sgExplode.add(new IntSetting.Builder() - .name("Existed Ticks") - .description("How many ticks should the crystal exist before attacking.") - .defaultValue(0) - .min(0) - .sliderRange(0, 20) - .visible(() -> existedMode.get() == DelayMode.Ticks) - .build() - ); - private final Setting sequential = sgExplode.add(new EnumSetting.Builder() - .name("Sequential") - .description("Doesn't place and attack during the same tick.") - .defaultValue(SequentialMode.Disabled) - .build() - ); - private final Setting instantAttack = sgExplode.add(new BoolSetting.Builder() - .name("Instant Attack") - .description("Delay isn't calculated for first attack.") - .defaultValue(true) - .build() - ); - private final Setting expSpeedLimit = sgExplode.add(new DoubleSetting.Builder() - .name("Explode Speed Limit") - .description("How many times to hit any crystal each second. 0 = no limit") - .defaultValue(0) - .min(0) - .sliderRange(0, 20) - .visible(instantAttack::get) - .build() - ); - private final Setting expSpeed = sgExplode.add(new DoubleSetting.Builder() - .name("Explode Speed") - .description("How many times to hit crystal each second.") - .defaultValue(4) - .range(0.01, 20) - .sliderRange(0.01, 20) - .build() - ); - private final Setting setDead = sgExplode.add(new BoolSetting.Builder() - .name("Set Dead") - .description("Hides the crystal after hitting it. Not needed since the module already is smart enough.") - .defaultValue(false) - .build() - ); - private final Setting setDeadDelay = sgExplode.add(new DoubleSetting.Builder() - .name("Set Dead Delay") - .description("How long after hitting should the crystal disappear.") - .defaultValue(0.05) - .range(0, 1) - .sliderRange(0, 1) - .visible(setDead::get) - .build() - ); - - //--------------------Switch--------------------// - private final Setting switchMode = sgSwitch.add(new EnumSetting.Builder() - .name("Switch Mode") - .description("Mode for switching to crystal in main hand.") - .defaultValue(SwitchMode.Disabled) - .build() - ); - private final Setting switchPenalty = sgSwitch.add(new DoubleSetting.Builder() - .name("Switch Penalty") - .description("Time to wait after switching before hitting crystals.") - .defaultValue(0.25) - .min(0) - .sliderRange(0, 1) - .build() - ); - - //--------------------Damage--------------------// - private final Setting dmgCheckMode = sgDamage.add(new EnumSetting.Builder() - .name("Dmg Check Mode") - .description("How safe are the placements (normal is good).") - .defaultValue(DmgCheckMode.Normal) - .build() - ); - private final Setting minPlace = sgDamage.add(new DoubleSetting.Builder() - .name("Min Place") - .description("Minimum damage to place.") - .defaultValue(4) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting maxPlace = sgDamage.add(new DoubleSetting.Builder() - .name("Max Place") - .description("Max self damage for placing.") - .defaultValue(8) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting minPlaceRatio = sgDamage.add(new DoubleSetting.Builder() - .name("Min Place Ratio") - .description("Max self damage ratio for placing (enemy / self).") - .defaultValue(1.4) - .min(0) - .sliderRange(0, 5) - .build() - ); - private final Setting maxFriendPlace = sgDamage.add(new DoubleSetting.Builder() - .name("Max Friend Place") - .description("Max friend damage for placing.") - .defaultValue(8) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting minFriendPlaceRatio = sgDamage.add(new DoubleSetting.Builder() - .name("Min Friend Place Ratio") - .description("Max friend damage ratio for placing (enemy / friend).") - .defaultValue(2) - .min(0) - .sliderRange(0, 5) - .build() - ); - private final Setting expMode = sgDamage.add(new EnumSetting.Builder() - .name("Explode Damage Mode") - .description("Which things should be checked for exploding.") - .defaultValue(ExplodeMode.FullCheck) - .build() - ); - private final Setting minExplode = sgDamage.add(new DoubleSetting.Builder() - .name("Min Explode") - .description("Minimum enemy damage for exploding a crystal.") - .defaultValue(2.5) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting maxExp = sgDamage.add(new DoubleSetting.Builder() - .name("Max Explode") - .description("Max self damage for exploding a crystal.") - .defaultValue(9) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting minExpRatio = sgDamage.add(new DoubleSetting.Builder() - .name("Min Explode Ratio") - .description("Max self damage ratio for exploding a crystal (enemy / self).") - .defaultValue(1.1) - .min(0) - .sliderRange(0, 5) - .build() - ); - private final Setting maxFriendExp = sgDamage.add(new DoubleSetting.Builder() - .name("Max Friend Explode") - .description("Max friend damage for exploding a crystal.") - .defaultValue(12) - .min(0) - .sliderRange(0, 20) - .build() - ); - private final Setting minFriendExpRatio = sgDamage.add(new DoubleSetting.Builder() - .name("Min Friend Explode Ratio") - .description("Min friend damage ratio for exploding a crystal (enemy / friend).") - .defaultValue(2) - .min(0) - .sliderRange(0, 5) - .build() - ); - private final Setting forcePop = sgDamage.add(new DoubleSetting.Builder() - .name("Force Pop") - .description("Ignores damage checks if any enemy will be popped in x hits.") - .defaultValue(1) - .min(0) - .sliderRange(0, 10) - .build() - ); - private final Setting antiFriendPop = sgDamage.add(new DoubleSetting.Builder() - .name("Anti Friend Pop") - .description("Cancels any action if any friend will be popped in x hits.") - .defaultValue(1) - .min(0) - .sliderRange(0, 10) - .build() - ); - private final Setting antiSelfPop = sgDamage.add(new DoubleSetting.Builder() - .name("Anti Self Pop") - .description("Cancels any action if you will be popped in x hits.") - .defaultValue(1) - .min(0) - .sliderRange(0, 10) - .build() - ); - - //--------------------ID-Predict--------------------// - private final Setting idPredict = sgID.add(new BoolSetting.Builder() - .name("ID Predict") - .description("Hits the crystal before it spawns.") - .defaultValue(false) - .build() - ); - private final Setting idStartOffset = sgID.add(new IntSetting.Builder() - .name("Id Start Offset") - .description("How many id's ahead should we attack.") - .defaultValue(1) - .min(0) - .sliderMax(10) - .build() - ); - private final Setting idOffset = sgID.add(new IntSetting.Builder() - .name("Id Packet Offset") - .description("How many id's ahead should we attack between id packets.") - .defaultValue(1) - .min(1) - .sliderMax(10) - .build() - ); - private final Setting idPackets = sgID.add(new IntSetting.Builder() - .name("Id Packets") - .description("How many packets to send.") - .defaultValue(1) - .min(1) - .sliderMax(10) - .build() - ); - private final Setting idDelay = sgID.add(new DoubleSetting.Builder() - .name("ID Start Delay") - .description("Starts sending id predict packets after this many seconds.") - .defaultValue(0.05) - .min(0) - .sliderRange(0, 1) - .build() - ); - private final Setting idPacketDelay = sgID.add(new DoubleSetting.Builder() - .name("ID Packet Delay") - .description("Waits this many seconds between sending ID packets.") - .defaultValue(0.05) - .min(0) - .sliderRange(0, 1) - .build() - ); - - //--------------------Extrapolation--------------------// - private final Setting selfExt = sgExtrapolation.add(new IntSetting.Builder() - .name("Self Extrapolation") - .description("How many ticks of movement should be predicted for self damage checks.") - .defaultValue(0) - .range(0, 100) - .sliderMax(20) - .build() - ); - private final Setting extrapolation = sgExtrapolation.add(new IntSetting.Builder() - .name("Extrapolation") - .description("How many ticks of movement should be predicted for enemy damage checks.") - .defaultValue(0) - .range(0, 100) - .sliderMax(20) - .build() - ); - private final Setting rangeExtrapolation = sgExtrapolation.add(new IntSetting.Builder() - .name("Range Extrapolation") - .description("How many ticks of movement should be predicted for attack ranges before placing.") - .defaultValue(0) - .range(0, 100) - .sliderMax(20) - .build() - ); - private final Setting hitboxExtrapolation = sgExtrapolation.add(new IntSetting.Builder() - .name("Hitbox Extrapolation") - .description("How many ticks of movement should be predicted for hitboxes in placing checks.") - .defaultValue(0) - .range(0, 100) - .sliderMax(20) - .build() - ); - private final Setting extSmoothness = sgExtrapolation.add(new IntSetting.Builder() - .name("Extrapolation Smoothening") - .description("How many earlier ticks should be used in average calculation for extrapolation motion.") - .defaultValue(2) - .range(1, 20) - .sliderRange(1, 20) - .build() - ); - - //--------------------Render--------------------// - private final Setting placeSwing = sgRender.add(new BoolSetting.Builder() - .name("Place Swing") - .description("Renders swing animation when placing a crystal.") - .defaultValue(true) - .build() - ); - private final Setting placeHand = sgRender.add(new EnumSetting.Builder() - .name("Place Hand") - .description("Which hand should be swung.") - .defaultValue(SwingHand.RealHand) - .visible(placeSwing::get) - .build() - ); - private final Setting attackSwing = sgRender.add(new BoolSetting.Builder() - .name("Attack Swing") - .description("Renders swing animation when placing a crystal.") - .defaultValue(true) - .build() - ); - private final Setting attackHand = sgRender.add(new EnumSetting.Builder() - .name("Attack Hand") - .description("Which hand should be swung.") - .defaultValue(SwingHand.RealHand) - .visible(attackSwing::get) - .build() - ); - private final Setting render = sgRender.add(new BoolSetting.Builder() - .name("Render") - .description("Renders box on placement.") - .defaultValue(true) - .build() - ); - private final Setting renderMode = sgRender.add(new EnumSetting.Builder() - .name("Render Mode") - .description("What should the render look like.") - .defaultValue(RenderMode.BlackOut) - .build() - ); - private final Setting renderTime = sgRender.add(new DoubleSetting.Builder() - .name("Render Time") - .description("How long the box should remain in full alpha value.") - .defaultValue(0.3) - .min(0) - .sliderRange(0, 10) - .visible(() -> renderMode.get().equals(RenderMode.Earthhack) || renderMode.get().equals(RenderMode.Future)) - .build() - ); - private final Setting fadeMode = sgRender.add(new EnumSetting.Builder() - .name("Fade Mode") - .description("How long the fading should take.") - .defaultValue(FadeMode.Normal) - .visible(() -> renderMode.get() == RenderMode.BlackOut) - .build() - ); - private final Setting earthFadeMode = sgRender.add(new EnumSetting.Builder() - .name("Earth Fade Mode") - .description(".") - .defaultValue(EarthFadeMode.Normal) - .visible(() -> renderMode.get() == RenderMode.Earthhack) - .build() - ); - private final Setting fadeTime = sgRender.add(new DoubleSetting.Builder() - .name("Fade Time") - .description("How long the fading should take.") - .defaultValue(1) - .min(0) - .sliderRange(0, 10) - .visible(() -> renderMode.get().equals(RenderMode.Earthhack) || renderMode.get().equals(RenderMode.Future)) - .build() - ); - private final Setting animationSpeed = sgRender.add(new DoubleSetting.Builder() - .name("Animation Move Speed") - .description("How fast should blackout mode box move.") - .defaultValue(1) - .min(0) - .sliderRange(0, 10) - .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) - .build() - ); - private final Setting animationMoveExponent = sgRender.add(new DoubleSetting.Builder() - .name("Animation Move Exponent") - .description("Moves faster when longer away from the target.") - .defaultValue(2) - .min(0) - .sliderRange(0, 10) - .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) - .build() - ); - private final Setting animationExponent = sgRender.add(new DoubleSetting.Builder() - .name("Animation Exponent") - .description("How fast should blackout mode box grow.") - .defaultValue(3) - .min(0) - .sliderRange(0, 10) - .visible(() -> renderMode.get().equals(RenderMode.BlackOut)) - .build() - ); - private final Setting shapeMode = sgRender.add(new EnumSetting.Builder() - .name("Shape Mode") - .description("Which parts of render should be rendered.") - .defaultValue(ShapeMode.Both) - .build() - ); - private final Setting lineColor = sgRender.add(new ColorSetting.Builder() - .name("Line Color") - .description("Line color of rendered boxes") - .defaultValue(new SettingColor(255, 0, 0, 255)) - .build() - ); - public final Setting color = sgRender.add(new ColorSetting.Builder() - .name("Side Color") - .description("Side color of rendered boxes") - .defaultValue(new SettingColor(255, 0, 0, 50)) - .build() - ); - - //--------------------Compatibility--------------------// - private final Setting autoMineDamage = sgCompatibility.add(new DoubleSetting.Builder() - .name("Auto Mine Damage") - .description("Prioritizes placing on automine target block.") - .defaultValue(1.1) - .min(1) - .sliderRange(1, 5) - .build() - ); - private final Setting amPlace = sgCompatibility.add(new BoolSetting.Builder() - .name("Auto Mine Place") - .description("Ignores automine block before if actually breaks.") - .defaultValue(true) - .build() - ); - private final Setting amProgress = sgCompatibility.add(new DoubleSetting.Builder() - .name("Auto Mine Progress") - .description("Ignores the block after it has reached this progress.") - .defaultValue(0.95) - .range(0, 1) - .sliderRange(0, 1) - .visible(amPlace::get) - .build() - ); - private final Setting amSpam = sgCompatibility.add(new BoolSetting.Builder() - .name("Auto Mine Spam") - .description("Spams crystals before the block breaks.") - .defaultValue(false) - .visible(amPlace::get) - .build() - ); - private final Setting amBroken = sgCompatibility.add(new EnumSetting.Builder() - .name("Auto Mine Broken") - .description("Doesn't place on automine block.") - .defaultValue(AutoMineBrokenMode.Near) - .build() - ); - private final Setting paAttack = sgCompatibility.add(new BoolSetting.Builder() - .name("Piston Crystal Attack") - .description("Doesn't attack the crystal placed by piston crystal.") - .defaultValue(true) - .build() - ); - private final Setting paPlace = sgCompatibility.add(new BoolSetting.Builder() - .name("Piston Crystal Placing") - .description("Doesn't place crystals when piston crystal is enabled.") - .defaultValue(true) - .build() - ); - - //--------------------Debug--------------------// - private final Setting renderExt = sgDebug.add(new BoolSetting.Builder() - .name("Render Extrapolation") - .description("Renders boxes at players' predicted positions.") - .defaultValue(false) - .build() - ); - private final Setting renderSelfExt = sgDebug.add(new BoolSetting.Builder() - .name("Render Self Extrapolation") - .description("Renders box at your predicted position.") - .defaultValue(false) - .build() - ); - - private long ticksEnabled = 0; - private double placeTimer = 0; - private double placeLimitTimer = 0; - private double delayTimer = 0; - private int delayTicks = 0; - - private BlockPos placePos = null; - private Direction placeDir = null; - private Entity expEntity = null; - private final TimerList attackedList = new TimerList<>(); - private final TimerList inhibitList = new TimerList<>(); - private final Map existedList = new HashMap<>(); - private final Map existedTicksList = new HashMap<>(); - private final Map own = new HashMap<>(); - private final Map extPos = new HashMap<>(); - private final Map extHitbox = new HashMap<>(); - private Vec3d rangePos = null; - private final List blocked = new ArrayList<>(); - private final Map earthMap = new HashMap<>(); - private double attackTimer = 0; - private double switchTimer = 0; - private int confirmed = Integer.MIN_VALUE; - private long lastMillis = System.currentTimeMillis(); - private boolean suicide = false; - public static boolean placing = false; - private long lastAttack = 0; - - private Vec3d renderTarget = null; - private Vec3d renderPos = null; - private double renderProgress = 0; - - private AutoMine autoMine = null; - - private int placed = 0; - - private double cps = 0; - private final List explosions = Collections.synchronizedList(new ArrayList<>()); - - private final List predicts = new ArrayList<>(); - private final List setDeads = new ArrayList<>(); - - @Override - public void onActivate() { - super.onActivate(); - ticksEnabled = 0; - - earthMap.clear(); - existedTicksList.clear(); - existedList.clear(); - blocked.clear(); - extPos.clear(); - own.clear(); - renderPos = null; - renderProgress = 0; - lastMillis = System.currentTimeMillis(); - attackedList.clear(); - lastAttack = 0; - - predicts.clear(); - setDeads.clear(); - } - - @Override - public String getInfoString() { - return String.format("%.1f", cps); - } - - @EventHandler(priority = EventPriority.HIGHEST) - private void onTickPost(TickEvent.Post event) { - delayTicks++; - ticksEnabled++; - placed++; - - if (mc.player == null || mc.world == null) return; - - if (autoMine == null) autoMine = Modules.get().get(AutoMine.class); - - ExtrapolationUtils.extrapolateMap(extPos, player -> player == mc.player ? selfExt.get() : extrapolation.get(), player -> extSmoothness.get()); - ExtrapolationUtils.extrapolateMap(extHitbox, player -> hitboxExtrapolation.get(), player -> extSmoothness.get()); - - Box rangeBox = ExtrapolationUtils.extrapolate(mc.player, rangeExtrapolation.get(), extSmoothness.get()); - if (rangeBox == null) rangePos = mc.player.getEyePos(); - else rangePos = new Vec3d((rangeBox.minX + rangeBox.maxX) / 2f, rangeBox.minY + mc.player.getEyeHeight(mc.player.getPose()), (rangeBox.minZ + rangeBox.maxZ) / 2f); - - List toRemove = new ArrayList<>(); - existedList.forEach((key, val) -> { - if (System.currentTimeMillis() - val >= 5000 + existed.get() * 1000) - toRemove.add(key); - }); - toRemove.forEach(existedList::remove); - - toRemove.clear(); - existedTicksList.forEach((key, val) -> { - if (ticksEnabled - val >= 100 + existedTicks.get()) - toRemove.add(key); - }); - toRemove.forEach(existedTicksList::remove); - - toRemove.clear(); - own.forEach((key, val) -> { - if (System.currentTimeMillis() - val >= 5000) - toRemove.add(key); - }); - toRemove.forEach(own::remove); - - if (performance.get()) updatePlacement(); - } - - @EventHandler(priority = EventPriority.HIGHEST + 1) - private void onRender3D(Render3DEvent event) { - attackedList.update(); - inhibitList.update(); - - if (autoMine == null) autoMine = Modules.get().get(AutoMine.class); - - suicide = Modules.get().isActive(Suicide.class); - double delta = (System.currentTimeMillis() - lastMillis) / 1000f; - lastMillis = System.currentTimeMillis(); - - cps = 0; - synchronized (explosions) { - explosions.removeIf(time -> { - double p = (System.currentTimeMillis() - time) / 1000D; - - if (p >= 5) return true; - - double d = p <= 4 ? 1 : 1 - (p - 4); - cps += d; - return false; - }); - } - cps /= 4.5; - - attackTimer = Math.max(attackTimer - delta, 0); - placeTimer = Math.max(placeTimer - delta * getSpeed(), 0); - placeLimitTimer += delta; - delayTimer += delta; - switchTimer = Math.max(0, switchTimer - delta); - - update(); - checkDelayed(); - - //Rendering - if (render.get()) { - switch (renderMode.get()) { - case BlackOut -> { - if (placePos != null && !isPaused() && holdingCheck()) { - renderProgress = Math.min(1, renderProgress + delta); - renderTarget = new Vec3d(placePos.getX(), placePos.getY(), placePos.getZ()); - } else { - renderProgress = Math.max(0, renderProgress - delta); - } - - if (renderTarget != null) { - renderPos = smoothMove(renderPos, renderTarget, delta * animationSpeed.get() * 5); - } - - if (renderPos != null) { - double r = 0.5 - Math.pow(1 - renderProgress, animationExponent.get()) / 2f; - - if (r >= 0.001) { - double down = -0.5; - double up = -0.5; - double width = 0.5; - - switch (fadeMode.get()) { - case Up -> { - up = 0; - down = -(r * 2); - } - case Down -> { - up = -1 + r * 2; - down = -1; - } - case Normal -> { - up = -0.5 + r; - down = -0.5 - r; - width = r; - } - } - Box box = new Box(renderPos.getX() + 0.5 - width, renderPos.getY() + down, renderPos.getZ() + 0.5 - width, - renderPos.getX() + 0.5 + width, renderPos.getY() + up, renderPos.getZ() + 0.5 + width); - - event.renderer.box(box, new Color(color.get().r, color.get().g, color.get().b, color.get().a), lineColor.get(), shapeMode.get(), 0); - } - } - } - case Future -> { - if (placePos != null && !isPaused() && holdingCheck()) { - renderPos = new Vec3d(placePos.getX(), placePos.getY(), placePos.getZ()); - renderProgress = fadeTime.get() + renderTime.get(); - } else { - renderProgress = Math.max(0, renderProgress - delta); - } - - if (renderProgress > 0 && renderPos != null) { - event.renderer.box(new Box(renderPos.getX(), renderPos.getY() - 1, renderPos.getZ(), - renderPos.getX() + 1, renderPos.getY(), renderPos.getZ() + 1), - new Color(color.get().r, color.get().g, color.get().b, (int) Math.round(color.get().a * Math.min(1, renderProgress / fadeTime.get()))), - new Color(lineColor.get().r, lineColor.get().g, lineColor.get().b, (int) Math.round(lineColor.get().a * Math.min(1, renderProgress / fadeTime.get()))), shapeMode.get(), 0); - } - } - case Earthhack -> { - List toRemove = new ArrayList<>(); - for (Map.Entry entry : earthMap.entrySet()) { - BlockPos pos = entry.getKey(); - Double[] alpha = entry.getValue(); - if (alpha[0] <= delta) { - toRemove.add(pos); - } else { - double r = Math.min(1, alpha[0] / alpha[1]) / 2f; - double down = -0.5; - double up = -0.5; - double width = 0.5; - - switch (earthFadeMode.get()) { - case Normal -> { - up = 1; - down = 0; - } - case Up -> { - up = 1; - down = 1 - (r * 2); - } - case Down -> { - up = r * 2; - down = 0; - } - case Shrink -> { - up = 0.5 + r; - down = 0.5 - r; - width = r; - } - } - - Box box = new Box(pos.getX() + 0.5 - width, pos.getY() + down, pos.getZ() + 0.5 - width, - pos.getX() + 0.5 + width, pos.getY() + up, pos.getZ() + 0.5 + width); - - event.renderer.box(box, - new Color(color.get().r, color.get().g, color.get().b, (int) Math.round(color.get().a * Math.min(1, alpha[0] / alpha[1]))), - new Color(lineColor.get().r, lineColor.get().g, lineColor.get().b, (int) Math.round(lineColor.get().a * Math.min(1, alpha[0] / alpha[1]))), shapeMode.get(), 0); - entry.setValue(new Double[]{alpha[0] - delta, alpha[1]}); - } - } - toRemove.forEach(earthMap::remove); - } - } - } - - if (mc.player != null) { - //Render extrapolation - if (renderExt.get()) { - extPos.forEach((name, bb) -> { - if (renderSelfExt.get() || !name.equals(mc.player)) - event.renderer.box(bb, color.get(), lineColor.get(), shapeMode.get(), 0); - }); - } - } - } - - @EventHandler(priority = EventPriority.HIGHEST) - private void onEntity(EntityAddedEvent event) { - confirmed = event.entity.getId(); - - if (event.entity.getBlockPos().equals(placePos)) explosions.add(System.currentTimeMillis()); - } - - @EventHandler(priority = EventPriority.HIGHEST) - private void onSend(PacketEvent.Send event) { - if (mc.player != null && mc.world != null) { - if (event.packet instanceof UpdateSelectedSlotC2SPacket) { - switchTimer = switchPenalty.get(); - } - - if (event.packet instanceof PlayerInteractBlockC2SPacket packet) { - - if (!(packet.getHand() == Hand.MAIN_HAND ? Managers.HOLDING.isHolding(Items.END_CRYSTAL) : mc.player.getOffHandStack().getItem() == Items.END_CRYSTAL)) - return; - - if (isOwn(packet.getBlockHitResult().getBlockPos().up())) own.remove(packet.getBlockHitResult().getBlockPos().up()); - - own.put(packet.getBlockHitResult().getBlockPos().up(), System.currentTimeMillis()); - blocked.add(OLEPOSSUtils.getCrystalBox(packet.getBlockHitResult().getBlockPos().up())); - addExisted(packet.getBlockHitResult().getBlockPos().up()); - } - } - } - - // Other stuff - private void update() { - placing = false; - expEntity = null; - - Hand hand = getHand(stack -> stack.getItem() == Items.END_CRYSTAL); - - Hand handToUse = hand; - if (!performance.get()) updatePlacement(); - - switch (switchMode.get()) { - case Simple -> { - int slot = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); - if (placePos != null && hand == null && slot >= 0) { - InvUtils.swap(slot, false); - handToUse = Hand.MAIN_HAND; - } - } - case Gapple -> { - int gapSlot = InvUtils.findInHotbar(OLEPOSSUtils::isGapple).slot(); - if (mc.options.useKey.isPressed() && Managers.HOLDING.isHolding(Items.END_CRYSTAL, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLDEN_APPLE) && gapSlot >= 0) { - if (getHand(OLEPOSSUtils::isGapple) == null) - InvUtils.swap(gapSlot, false); - handToUse = getHand(itemStack -> itemStack.getItem() == Items.END_CRYSTAL); - } else if (Managers.HOLDING.isHolding(Items.END_CRYSTAL, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLDEN_APPLE)) { - int slot = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); - if (placePos != null && hand == null && slot >= 0) { - InvUtils.swap(slot, false); - handToUse = Hand.MAIN_HAND; - } - } - } - } - - if (placePos != null && placeDir != null) { - if (!isPaused() && (!paPlace.get() || !Modules.get().isActive(PistonCrystal.class))) { - int silentSlot = InvUtils.find(itemStack -> itemStack.getItem() == Items.END_CRYSTAL).slot(); - int hotbar = InvUtils.findInHotbar(Items.END_CRYSTAL).slot(); - if (handToUse != null || (switchMode.get() == SwitchMode.Silent && hotbar >= 0) || ((switchMode.get() == SwitchMode.PickSilent || switchMode.get() == SwitchMode.InvSilent) && silentSlot >= 0)) { - placing = true; - if (!SettingUtils.shouldRotate(RotationType.Interact) || Managers.ROTATION.start(placePos.down(), smartRot.get() ? new Vec3d(placePos.getX() + 0.5, placePos.getY(), placePos.getZ() + 0.5) : null, priority, RotationType.Interact, Objects.hash(name + "placing"))) { - if (speedCheck() && delayCheck()) - placeCrystal(placePos.down(), placeDir, handToUse, silentSlot, hotbar); - } - } - } - } - - PistonCrystal pa = Modules.get().get(PistonCrystal.class); - double[] value = null; - - if (!isPaused() && (hand != null || switchMode.get() == SwitchMode.Silent || switchMode.get() == SwitchMode.PickSilent || switchMode.get() == SwitchMode.InvSilent) && explode.get()) { - for (Entity en : mc.world.getEntities()) { - if (!(en instanceof EndCrystalEntity)) continue; - if (paAttack.get() && pa.isActive() && en.getBlockPos().equals(pa.crystalPos)) continue; - if (inhibitList.contains(en.getId())) continue; - if (switchTimer > 0) continue; - - double[] dmg = getDmg(en.getPos(), true)[0]; - - if (!canExplode(en.getPos())) continue; - - if ((expEntity == null || value == null) || ((dmgCheckMode.get().equals(DmgCheckMode.Normal) && dmg[0] > value[0]) || (dmgCheckMode.get().equals(DmgCheckMode.Safe) && dmg[2] / dmg[0] < value[2] / dmg[0]))) { - expEntity = en; - value = dmg; - } - } - } - - if (expEntity != null) { - if (multiTaskCheck() && !isAttacked(expEntity.getId()) && attackDelayCheck() && existedCheck(expEntity.getBlockPos())) { - if (!SettingUtils.shouldRotate(RotationType.Attacking) || startAttackRot()) { - explode(expEntity.getId(), expEntity.getPos()); - } - } - } else if (SettingUtils.shouldRotate(RotationType.Attacking)) Managers.ROTATION.end(Objects.hash(name + "attacking")); - } - - private boolean attackDelayCheck() { - if (instantAttack.get()) - return expSpeedLimit.get() <= 0 || System.currentTimeMillis() > lastAttack + 1000 / expSpeedLimit.get(); - else - return System.currentTimeMillis() > lastAttack + 1000 / expSpeed.get(); - } - - private boolean startAttackRot() { - return (Managers.ROTATION.start(expEntity.getBoundingBox(), smartRot.get() ? expEntity.getPos() : null, priority + (!isAttacked(expEntity.getId()) && blocksPlacePos(expEntity) ? -0.1 : 0.1), RotationType.Attacking, Objects.hash(name + "attacking"))); - } - - private boolean blocksPlacePos(Entity entity) { - return placePos != null && entity.getBoundingBox().intersects(new Box(placePos.getX(), placePos.getY(), placePos.getZ(), placePos.getX() + 1, placePos.getY() + (SettingUtils.cc() ? 1 : 2), placePos.getZ() + 1)); - } - - private boolean isAlive(Box box) { - if (box == null) return true; - - for (Entity en : mc.world.getEntities()) { - if (!(en instanceof EndCrystalEntity)) continue; - if (bbEquals(box, en.getBoundingBox())) return true; - } - return false; - } - - private boolean bbEquals(Box box1, Box box2) { - return box1.minX == box2.minX && - box1.minY == box2.minY && - box1.minZ == box2.minZ && - box1.maxX == box2.maxX && - box1.maxY == box2.maxY && - box1.maxZ == box2.maxZ; - } - - private boolean speedCheck() { - - if (speedLimit.get() > 0 && placeLimitTimer < 1 / speedLimit.get()) - return false; - - if (instantPlace.get() && !shouldSlow() && !isBlocked(placePos)) - return true; - - return placeTimer <= 0; - } - - private boolean holdingCheck() { - return switch (switchMode.get()) { - case Silent -> InvUtils.findInHotbar(Items.END_CRYSTAL).slot() >= 0; - case PickSilent, InvSilent -> InvUtils.find(Items.END_CRYSTAL).slot() >= 0; - default -> getHand(itemStack -> itemStack.getItem() == Items.END_CRYSTAL) != null; - }; - } - - private void updatePlacement() { - if (!place.get()) { - placePos = null; - placeDir = null; - return; - } - placePos = getPlacePos(); - } - - private void placeCrystal(BlockPos pos, Direction dir, Hand handToUse, int sl, int hsl) { - if (pos != null && mc.player != null) { - if (renderMode.get().equals(RenderMode.Earthhack)) { - if (!earthMap.containsKey(pos)) - earthMap.put(pos, new Double[]{fadeTime.get() + renderTime.get(), fadeTime.get()}); - else - earthMap.replace(pos, new Double[]{fadeTime.get() + renderTime.get(), fadeTime.get()}); - } - - blocked.add(new Box(pos.getX() - 0.5, pos.getY() + 1, pos.getZ() - 0.5, pos.getX() + 1.5, pos.getY() + 2, pos.getZ() + 1.5)); - - boolean switched = handToUse == null; - if (switched) { - switch (switchMode.get()) { - case PickSilent -> BOInvUtils.pickSwitch(sl); - case Silent -> InvUtils.swap(hsl, true); - case InvSilent -> BOInvUtils.invSwitch(sl); - } - } - - addExisted(pos.up()); - - if (!isOwn(pos.up())) own.put(pos.up(), System.currentTimeMillis()); - else { - own.remove(pos.up()); - own.put(pos.up(), System.currentTimeMillis()); - } - - placeLimitTimer = 0; - placeTimer = 1; - placed = 0; - - interactBlock(switched ? Hand.MAIN_HAND : handToUse, pos.toCenterPos(), dir, pos); - - if (placeSwing.get()) clientSwing(placeHand.get(), switched ? Hand.MAIN_HAND : handToUse); - - if (SettingUtils.shouldRotate(RotationType.Interact)) - Managers.ROTATION.end(Objects.hash(name + "placing")); - - if (switched) { - switch (switchMode.get()) { - case PickSilent -> BOInvUtils.pickSwapBack(); - case Silent -> InvUtils.swapBack(); - case InvSilent -> BOInvUtils.swapBack(); - } - } - if (idPredict.get()) { - int highest = getHighest(); - - int id = highest + idStartOffset.get(); - for (int i = 0; i < idPackets.get() * idOffset.get(); i += idOffset.get()) { - addPredict(id + i, new Vec3d(pos.getX() + 0.5, pos.getY() + 1, pos.getZ() + 0.5), idDelay.get() + idPacketDelay.get() * i); - } - } - } - } - - private boolean delayCheck() { - if (placeDelayMode.get() == DelayMode.Seconds) - return delayTimer >= placeDelay.get(); - return delayTicks >= placeDelayTicks.get(); - } - - private boolean multiTaskCheck() { - return placed >= sequential.get().ticks; - } - - private int getHighest() { - int highest = confirmed; - for (Entity entity : mc.world.getEntities()) { - if (entity.getId() > highest) highest = entity.getId(); - } - if (highest > confirmed) confirmed = highest; - return highest; - } - - private boolean isBlocked(BlockPos pos) { - Box box = new Box(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 2, pos.getZ() + 1); - for (Box bb : blocked) { - if (bb.intersects(box)) return true; - } - return false; - } - - private boolean isAttacked(int id) { - return attackedList.contains(id); - } - - private void explode(int id, Vec3d vec) { - attackEntity(id, OLEPOSSUtils.getCrystalBox(vec), vec); - } - - private void attackEntity(int id, Box bb, Vec3d vec) { - if (mc.player != null) { - lastAttack = System.currentTimeMillis(); - attackedList.add(id, 1 / expSpeed.get()); - if (inhibit.get()) inhibitList.add(id, 0.5); - - delayTimer = 0; - delayTicks = 0; - - removeExisted(BlockPos.ofFloored(vec)); - - SettingUtils.registerAttack(bb); - PlayerInteractEntityC2SPacket packet = PlayerInteractEntityC2SPacket.attack(mc.player, mc.player.isSneaking()); - ((IInteractEntityC2SPacket) packet).setId(id); - - SettingUtils.swing(SwingState.Pre, SwingType.Attacking, Hand.MAIN_HAND); - - sendPacket(packet); - - SettingUtils.swing(SwingState.Post, SwingType.Attacking, Hand.MAIN_HAND); - if (attackSwing.get()) clientSwing(attackHand.get(), Hand.MAIN_HAND); - - blocked.clear(); - if (setDead.get()) { - Entity entity = mc.world.getEntityById(id); - if (entity == null) return; - - addSetDead(entity, setDeadDelay.get()); - } - } - } - - private boolean existedCheck(BlockPos pos) { - if (existedMode.get() == DelayMode.Seconds) - return !existedList.containsKey(pos) || System.currentTimeMillis() > existedList.get(pos) + existed.get() * 1000; - else - return !existedTicksList.containsKey(pos) || ticksEnabled >= existedTicksList.get(pos) + existedTicks.get(); - } - - private void addExisted(BlockPos pos) { - if (existedMode.get() == DelayMode.Seconds) { - if (!existedList.containsKey(pos)) existedList.put(pos, System.currentTimeMillis()); - } else { - if (!existedTicksList.containsKey(pos)) existedTicksList.put(pos, ticksEnabled); - } - } - - private void removeExisted(BlockPos pos) { - if (existedMode.get() == DelayMode.Seconds) existedList.remove(pos); - else existedTicksList.remove(pos); - } - - private boolean canExplode(Vec3d vec) { - if (onlyOwn.get() && !isOwn(vec)) return false; - if (!inExplodeRange(vec)) return false; - - double[][] result = getDmg(vec, true); - return explodeDamageCheck(result[0], result[1], isOwn(vec)); - } - - private boolean canExplodePlacing(Vec3d vec) { - if (onlyOwn.get() && !isOwn(vec)) return false; - if (!inExplodeRangePlacing(vec)) return false; - - double[][] result = getDmg(vec, false); - return explodeDamageCheck(result[0], result[1], isOwn(vec)); - } - - private Hand getHand(Predicate predicate) { - return predicate.test(Managers.HOLDING.getStack()) ? Hand.MAIN_HAND : - predicate.test(mc.player.getOffHandStack()) ? Hand.OFF_HAND : null; - } - - private boolean isPaused() { - return pauseEat.get() && mc.player.isUsingItem(); - } - - private void setEntityDead(Entity en) { - mc.world.removeEntity(en.getId(), Entity.RemovalReason.KILLED); - } - - private BlockPos getPlacePos() { - - int r = (int) Math.ceil(Math.max(SettingUtils.getPlaceRange(), SettingUtils.getPlaceWallsRange())); - //Used in placement calculation - BlockPos bestPos = null; - Direction bestDir = null; - double[] highest = null; - - BlockPos pPos = BlockPos.ofFloored(mc.player.getEyePos()); - - for (int x = -r; x <= r; x++) { - for (int y = -r; y <= r; y++) { - for (int z = -r; z <= r; z++) { - BlockPos pos = pPos.add(x, y, z); - // Checks if crystal can be placed - if (!air(pos) || !(!SettingUtils.oldCrystals() || air(pos.up())) || !crystalBlock(pos.down()) || blockBroken(pos.down())) continue; - - // Checks if there is possible placing direction - Direction dir = SettingUtils.getPlaceOnDirection(pos.down()); - if (dir == null) continue; - - // Checks if the placement is in range - if (!inPlaceRange(pos.down()) || !inExplodeRangePlacing(new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5))) continue; - - // Calculates damages and healths - double[][] result = getDmg(new Vec3d(pos.getX() + 0.5, pos.getY(), pos.getZ() + 0.5), false); - - // Checks if damages are valid - if (!placeDamageCheck(result[0], result[1], highest)) continue; - - // Checks if placement is blocked by other entities (other than players) - Box box = new Box(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + (SettingUtils.cc() ? 1 : 2), pos.getZ() + 1); - - if (BOEntityUtils.intersectsWithEntity(box, this::validForIntersect, extHitbox)) continue; - - // Sets best pos to calculated one - bestDir = dir; - bestPos = pos; - highest = result[0]; - } - } - } - - placeDir = bestDir; - return bestPos; - } - - private boolean placeDamageCheck(double[] dmg, double[] health, double[] highest) { - // 0 = enemy, 1 = friend, 2 = self - - // Dmg Check - if (highest != null) { - if (dmgCheckMode.get().equals(DmgCheckMode.Normal) && dmg[0] < highest[0]) return false; - if (dmgCheckMode.get().equals(DmgCheckMode.Safe) && dmg[2] / dmg[0] > highest[2] / highest[0]) return false; - } - - // Force/anti-pop check - double playerHP = mc.player.getHealth() + mc.player.getAbsorptionAmount(); - - if (playerHP >= 0 && dmg[2] * antiSelfPop.get() >= playerHP) return false; - if (health[1] >= 0 && dmg[1] * antiFriendPop.get() >= health[1]) return false; - if (health[0] >= 0 && dmg[0] * forcePop.get() >= health[0]) return true; - - // Min Damage - if (dmg[0] < minPlace.get()) return false; - - // Max Damage - if (dmg[1] > maxFriendPlace.get()) return false; - if (dmg[1] >= 0 && dmg[0] / dmg[1] < minFriendPlaceRatio.get()) return false; - if (dmg[2] > maxPlace.get()) return false; - return dmg[2] < 0 || dmg[0] / dmg[2] >= minPlaceRatio.get(); - } - - private boolean explodeDamageCheck(double[] dmg, double[] health, boolean own) { - boolean checkOwn = expMode.get() == ExplodeMode.FullCheck - || expMode.get() == ExplodeMode.SelfDmgCheck - || expMode.get() == ExplodeMode.SelfDmgOwn - || expMode.get() == ExplodeMode.AlwaysOwn; - - boolean checkDmg = expMode.get() == ExplodeMode.FullCheck - || (expMode.get() == ExplodeMode.SelfDmgOwn && !own) - || (expMode.get() == ExplodeMode.AlwaysOwn && !own); - - // 0 = enemy, 1 = friend, 2 = self - - // Force/anti-pop check - double playerHP = mc.player.getHealth() + mc.player.getAbsorptionAmount(); - if (checkOwn) { - if (playerHP >= 0 && dmg[2] * forcePop.get() >= playerHP) return false; - if (health[1] >= 0 && dmg[1] * antiFriendPop.get() >= health[1]) return false; - } - - if (checkDmg) { - if (health[0] >= 0 && dmg[0] * forcePop.get() >= health[0]) return true; - if (dmg[0] < minExplode.get()) return false; - - if (dmg[1] >= 0 && dmg[0] / dmg[1] < minFriendExpRatio.get()) return false; - if (dmg[2] >= 0 && dmg[0] / dmg[2] < minExpRatio.get()) return false; - } - - if (checkOwn) { - if (dmg[1] > maxFriendExp.get()) return false; - return dmg[2] <= maxExp.get(); - } - return true; - } - - private boolean isOwn(Vec3d vec) { - return isOwn(BlockPos.ofFloored(vec)); - } - - private boolean isOwn(BlockPos pos) { - for (Map.Entry entry : own.entrySet()) { - if (entry.getKey().equals(pos)) return true; - } - return false; - } - - private double[][] getDmg(Vec3d vec, boolean attack) { - double self = BODamageUtils.crystalDamage(mc.player, extPos.containsKey(mc.player) ? extPos.get(mc.player) : mc.player.getBoundingBox(), vec, ignorePos(attack), ignoreTerrain.get()); - - if (suicide) return new double[][]{new double[]{self, -1, -1}, new double[]{20, 20}}; - - double highestEnemy = -1; - double highestFriend = -1; - double enemyHP = -1; - double friendHP = -1; - for (Map.Entry entry : extPos.entrySet()) { - AbstractClientPlayerEntity player = entry.getKey(); - Box box = entry.getValue(); - if (player.getHealth() <= 0 || player == mc.player) continue; - - double dmg = BODamageUtils.crystalDamage(player, box, vec, ignorePos(attack), ignoreTerrain.get()); - if (BlockPos.ofFloored(vec).down().equals(autoMine.targetPos())) - dmg *= autoMineDamage.get(); - double hp = player.getHealth() + player.getAbsorptionAmount(); - - // friend - if (Friends.get().isFriend(player)) { - if (dmg > highestFriend) { - highestFriend = dmg; - friendHP = hp; - } - } - // enemy - else if (dmg > highestEnemy) { - highestEnemy = dmg; - enemyHP = hp; - } - } - - return new double[][]{new double[]{highestEnemy, highestFriend, self}, new double[]{enemyHP, friendHP}}; - } - - private boolean air(BlockPos pos) { - return mc.world.getBlockState(pos).getBlock() instanceof AirBlock; - } - - private boolean crystalBlock(BlockPos pos) { - return mc.world.getBlockState(pos).getBlock().equals(Blocks.OBSIDIAN) || - mc.world.getBlockState(pos).getBlock().equals(Blocks.BEDROCK); - } - - private boolean inPlaceRange(BlockPos pos) { - return SettingUtils.inPlaceRange(pos); - } - - private boolean inExplodeRangePlacing(Vec3d vec) { - return SettingUtils.inAttackRange(new Box(vec.getX() - 1, vec.getY(), vec.getZ() - 1, vec.getX() + 1, vec.getY() + 2, vec.getZ() + 1), rangePos != null ? rangePos : null); - } - - private boolean inExplodeRange(Vec3d vec) { - return SettingUtils.inAttackRange(new Box(vec.getX() - 1, vec.getY(), vec.getZ() - 1, vec.getX() + 1, vec.getY() + 2, vec.getZ() + 1)); - } - - private double getSpeed() { - return shouldSlow() ? slowSpeed.get() : placeSpeed.get(); - } - - private boolean shouldSlow() { - return placePos != null && getDmg(new Vec3d(placePos.getX() + 0.5, placePos.getY(), placePos.getZ() + 0.5), false)[0][0] <= slowDamage.get(); - } - - private Vec3d smoothMove(Vec3d current, Vec3d target, double delta) { - if (current == null) return target; - - double absX = Math.abs(current.x - target.x); - double absY = Math.abs(current.y - target.y); - double absZ = Math.abs(current.z - target.z); - - double x = (absX + Math.pow(absX, animationMoveExponent.get() - 1)) * delta; - double y = (absX + Math.pow(absY, animationMoveExponent.get() - 1)) * delta; - double z = (absX + Math.pow(absZ, animationMoveExponent.get() - 1)) * delta; - - return new Vec3d(current.x > target.x ? Math.max(target.x, current.x - x) : Math.min(target.x, current.x + x), - current.y > target.y ? Math.max(target.y, current.y - y) : Math.min(target.y, current.y + y), - current.z > target.z ? Math.max(target.z, current.z - z) : Math.min(target.z, current.z + z)); - } - - private boolean validForIntersect(Entity entity) { - if (entity instanceof EndCrystalEntity && canExplodePlacing(entity.getPos())) - return false; - - return !(entity instanceof PlayerEntity) || !entity.isSpectator(); - } - - private BlockPos ignorePos(boolean attack) { - if (!amPlace.get()) return null; - if (!amSpam.get() && attack) return null; - if (autoMine == null || !autoMine.isActive()) return null; - if (autoMine.targetPos() == null) return null; - - return autoMine.getMineProgress() > amProgress.get() ? autoMine.targetPos() : null; - } - - private boolean blockBroken(BlockPos pos) { - if (!amPlace.get()) return false; - - if (autoMine == null || !autoMine.isActive()) return false; - if (autoMine.targetPos() == null) return false; - if (!autoMine.targetPos().equals(pos)) return false; - - double progress = autoMine.getMineProgress(); - - if (progress >= 1 && !amBroken.get().broken) return true; - if (progress >= amProgress.get() && !amBroken.get().near) return true; - return progress < amProgress.get() && !amBroken.get().normal; - } - - private void addPredict(int id, Vec3d pos, double delay) { - predicts.add(new Predict(id, pos, Math.round(System.currentTimeMillis() + delay * 1000))); - } - - private void addSetDead(Entity entity, double delay) { - setDeads.add(new SetDead(entity, Math.round(System.currentTimeMillis() + delay * 1000))); - } - - private void checkDelayed() { - List toRemove = new ArrayList<>(); - for (Predict p : predicts) { - if (System.currentTimeMillis() >= p.time) { - explode(p.id, p.pos); - toRemove.add(p); - } - } - toRemove.forEach(predicts::remove); - - List toRemove2 = new ArrayList<>(); - for (SetDead p : setDeads) { - if (System.currentTimeMillis() >= p.time) { - setEntityDead(p.entity); - toRemove2.add(p); - } - } - toRemove2.forEach(setDeads::remove); - } - - public enum DmgCheckMode { - Normal, - Safe - } - - public enum RenderMode { - BlackOut, - Future, - Earthhack - } - - public enum SwitchMode { - Disabled, - Simple, - Gapple, - Silent, - InvSilent, - PickSilent - } - - public enum SequentialMode { - Disabled(0), - Weak(1), - Strong(2), - Strict(3); - - public final int ticks; - - SequentialMode(int ticks) { - this.ticks = ticks; - } - } - - public enum ExplodeMode { - FullCheck, - SelfDmgCheck, - SelfDmgOwn, - AlwaysOwn, - Always - } - - public enum DelayMode { - Seconds, - Ticks - } - - public enum EarthFadeMode { - Normal, - Up, - Down, - Shrink - } - - public enum FadeMode { - Up, - Down, - Normal - } - - public enum AutoMineBrokenMode { - Near(true, false, false), - Broken(true, true, false), - Never(false, false, false), - Always(true, true, true); - - public final boolean normal; - public final boolean near; - public final boolean broken; - - AutoMineBrokenMode(boolean normal, boolean near, boolean broken) { - this.normal = normal; - this.near = near; - this.broken = broken; - } - } - - private record Predict(int id, Vec3d pos, long time) { - } - - private record SetDead(Entity entity, long time) { - } -} diff --git a/src/main/java/com/genyo/addon/modules/GenyoKristaj.java b/src/main/java/com/genyo/addon/modules/TescoCrystal.java similarity index 98% rename from src/main/java/com/genyo/addon/modules/GenyoKristaj.java rename to src/main/java/com/genyo/addon/modules/TescoCrystal.java index ddae830..e7fd6ef 100644 --- a/src/main/java/com/genyo/addon/modules/GenyoKristaj.java +++ b/src/main/java/com/genyo/addon/modules/TescoCrystal.java @@ -1,6 +1,5 @@ package com.genyo.addon.modules; -import com.genyo.addon.GenyoAddon; import com.google.common.util.concurrent.AtomicDouble; import it.unimi.dsi.fastutil.ints.*; import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; @@ -16,8 +15,8 @@ import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.friends.Friends; +import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; -import meteordevelopment.meteorclient.systems.modules.combat.BedAura; import meteordevelopment.meteorclient.utils.entity.DamageUtils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.Target; @@ -62,8 +61,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -public class GenyoKristaj extends Module { - +public class TescoCrystal extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgSwitch = settings.createGroup("Switch"); private final SettingGroup sgPlace = settings.createGroup("Place"); @@ -597,8 +595,8 @@ public class GenyoKristaj extends Module { private double renderDamage; - public GenyoKristaj() { - super(GenyoAddon.GENYO, "genyo-kristaj", "ez jobb mert a több az mindig jobb."); + public TescoCrystal() { + super(Categories.Combat, "crystal-aura", "Automatically places and attacks crystals."); } @Override @@ -706,6 +704,14 @@ private void onPreTick(TickEvent.Pre event) { } } + @EventHandler(priority = EventPriority.LOWEST - 666) + private void onPreTickLast(TickEvent.Pre event) { + // Rotate to last rotation + if (rotate.get() && lastRotationTimer < getLastRotationStopDelay() && !didRotateThisTick) { + Rotations.rotate(isLastRotationPos ? Rotations.getYaw(lastRotationPos) : lastYaw, isLastRotationPos ? Rotations.getPitch(lastRotationPos) : lastPitch, -100, null); + } + } + @EventHandler private void onEntityAdded(EntityAddedEvent event) { if (!(event.entity instanceof EndCrystalEntity)) return; @@ -854,7 +860,7 @@ private void doBreak(Entity crystal) { } private boolean isValidWeaknessItem(ItemStack itemStack, Entity crystal) { - return DamageUtils.getAttackDamage(mc.player, (LivingEntity) crystal, itemStack) > 0; + return DamageUtils.getAttackDamage(mc.player, crystal, itemStack) > 0; } private void attackCrystal(Entity entity) { @@ -1015,8 +1021,7 @@ private void placeCrystal(BlockHitResult result, double damage, BlockPos support FindItemResult item = InvUtils.findInHotbar(targetItem); if (!item.found()) return; - // int prevSlot = mc.player.getInventory().getSelectedSlot(); - int prevSlot = InvUtils.previousSlot; + int prevSlot = mc.player.getInventory().getSelectedSlot(); if (autoSwitch.get() != AutoSwitchMode.None && !item.isOffhand()) InvUtils.swap(item.slot(), false); @@ -1118,7 +1123,8 @@ private boolean shouldFacePlace() { if (itemStack == null || itemStack.isEmpty()) { if (facePlaceArmor.get()) return true; - } else { + } + else { if ((double) (itemStack.getMaxDamage() - itemStack.getDamage()) / itemStack.getMaxDamage() * 100 <= facePlaceDurability.get()) return true; } } @@ -1210,7 +1216,6 @@ private void findTargets() { if (livingEntity instanceof PlayerEntity player) { if (player.getAbilities().creativeMode || livingEntity == mc.player) continue; if (!player.isAlive() || !Friends.get().shouldAttack(player)) continue; - //TODO: prioritize enemies if (ignoreNakeds.get()) { if (player.getOffHandStack().isEmpty() @@ -1381,5 +1386,4 @@ public enum RenderMode { Gradient, None } - } diff --git a/src/main/java/com/genyo/addon/render/Render2DEngine.java b/src/main/java/com/genyo/addon/render/Render2DEngine.java new file mode 100644 index 0000000..874b2e0 --- /dev/null +++ b/src/main/java/com/genyo/addon/render/Render2DEngine.java @@ -0,0 +1,4 @@ +package com.genyo.addon.render; + +public class Render2DEngine { +} diff --git a/src/main/java/com/genyo/addon/render/Render3DEngine.java b/src/main/java/com/genyo/addon/render/Render3DEngine.java new file mode 100644 index 0000000..157b29d --- /dev/null +++ b/src/main/java/com/genyo/addon/render/Render3DEngine.java @@ -0,0 +1,4 @@ +package com.genyo.addon.render; + +public class Render3DEngine { +} diff --git a/src/main/java/com/genyo/addon/utils/MathUtil.java b/src/main/java/com/genyo/addon/utils/MathUtil.java new file mode 100644 index 0000000..bd74a5a --- /dev/null +++ b/src/main/java/com/genyo/addon/utils/MathUtil.java @@ -0,0 +1,4 @@ +package com.genyo.addon.utils; + +public class MathUtil { +} diff --git a/src/main/resources/genyo.accesswidener b/src/main/resources/genyo.accesswidener new file mode 100644 index 0000000..e69de29 From 995c1ffb840e8a0479accf95768206f63abdce69 Mon Sep 17 00:00:00 2001 From: wuritz Date: Sun, 6 Jul 2025 22:04:26 +0200 Subject: [PATCH 3/4] angel hulkenberg --- build.gradle | 4 + src/main/java/com/genyo/addon/GenyoAddon.java | 7 + .../com/genyo/addon/events/TotemPopEvent.java | 13 + .../com/genyo/addon/hud/PvPNeccessaryHud.java | 16 +- .../genyo/addon/managers/CombatManager.java | 36 ++ .../com/genyo/addon/managers/Managers.java | 9 + .../java/com/genyo/addon/mixin/IEntity.java | 15 + .../addon/modules/AngelSexHulkenberg.java | 213 ++++++- .../com/genyo/addon/modules/TescoCrystal.java | 538 +++--------------- .../genyo/addon/render/Render2DEngine.java | 9 + .../genyo/addon/render/Render3DEngine.java | 7 + .../java/com/genyo/addon/utils/MathUtil.java | 9 + src/main/resources/fabric.mod.json | 1 + src/main/resources/genyo.accesswidener | 26 + src/main/resources/genyo.mixins.json | 3 +- 15 files changed, 424 insertions(+), 482 deletions(-) diff --git a/build.gradle b/build.gradle index 429771b..faedcaf 100644 --- a/build.gradle +++ b/build.gradle @@ -8,6 +8,10 @@ base { group = project.maven_group } +loom { + accessWidenerPath = file("src/main/resources/genyo.accesswidener") +} + repositories { maven { name = "Meteor Dev Releases" diff --git a/src/main/java/com/genyo/addon/GenyoAddon.java b/src/main/java/com/genyo/addon/GenyoAddon.java index 7177e91..9d03740 100644 --- a/src/main/java/com/genyo/addon/GenyoAddon.java +++ b/src/main/java/com/genyo/addon/GenyoAddon.java @@ -2,7 +2,10 @@ import com.genyo.addon.gui.EnemiesTab; import com.genyo.addon.hud.PvPNeccessaryHud; +import com.genyo.addon.managers.Managers; +import com.genyo.addon.modules.AngelSexHulkenberg; import com.genyo.addon.modules.GenyoAutoEZ; +import com.genyo.addon.modules.TescoCrystal; import com.genyo.addon.systems.enemies.Enemies; import com.mojang.logging.LogUtils; import meteordevelopment.meteorclient.addons.GithubRepo; @@ -27,9 +30,13 @@ public void onInitialize() { Systems.add(new Enemies()); Modules.get().add(new GenyoAutoEZ()); + Modules.get().add(new TescoCrystal()); + Modules.get().add(new AngelSexHulkenberg()); Tabs.add(new EnemiesTab()); + Managers.subscribe(); + // HUD Hud.get().register(PvPNeccessaryHud.INFO); } diff --git a/src/main/java/com/genyo/addon/events/TotemPopEvent.java b/src/main/java/com/genyo/addon/events/TotemPopEvent.java index 873ab64..c004f21 100644 --- a/src/main/java/com/genyo/addon/events/TotemPopEvent.java +++ b/src/main/java/com/genyo/addon/events/TotemPopEvent.java @@ -1,4 +1,17 @@ package com.genyo.addon.events; +import net.minecraft.entity.player.PlayerEntity; + public class TotemPopEvent { + private static final TotemPopEvent INSTANCE = new TotemPopEvent(); + + public PlayerEntity entity; + public int pops; + + public static TotemPopEvent get(PlayerEntity entity, int pops) { + INSTANCE.entity = entity; + INSTANCE.pops = pops; + + return INSTANCE; + } } diff --git a/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java b/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java index 89b5ee5..b1d4ae0 100644 --- a/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java +++ b/src/main/java/com/genyo/addon/hud/PvPNeccessaryHud.java @@ -41,13 +41,13 @@ public class PvPNeccessaryHud extends HudElement { // Scale public final Setting margin = sgScale.add(new IntSetting.Builder() - .name("margin") - .description("Két dolog közötti hely") - .defaultValue(0) - .onChanged(aInt -> calculateSize()) - .min(0) - .sliderRange(0, 10) - .build() + .name("margin") + .description("Két dolog közötti hely") + .defaultValue(0) + .onChanged(aInt -> calculateSize()) + .min(0) + .sliderRange(0, 10) + .build() ); public final Setting customScale = sgScale.add(new BoolSetting.Builder() @@ -69,7 +69,7 @@ public class PvPNeccessaryHud extends HudElement { .build() ); - // Background + // Backgroundx public final Setting background = sgBackground.add(new BoolSetting.Builder() .name("background") diff --git a/src/main/java/com/genyo/addon/managers/CombatManager.java b/src/main/java/com/genyo/addon/managers/CombatManager.java index a2a6578..09292cd 100644 --- a/src/main/java/com/genyo/addon/managers/CombatManager.java +++ b/src/main/java/com/genyo/addon/managers/CombatManager.java @@ -1,4 +1,40 @@ package com.genyo.addon.managers; +import com.genyo.addon.events.TotemPopEvent; +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.events.packets.PacketEvent; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityStatuses; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket; + +import java.util.HashMap; + +import static meteordevelopment.meteorclient.MeteorClient.mc; + public class CombatManager { + + public HashMap popList = new HashMap<>(); + + @EventHandler + public void onPacketReceive(PacketEvent.Receive event) { + + if (event.packet instanceof EntityStatusS2CPacket pac) { + if (pac.getStatus() == EntityStatuses.USE_TOTEM_OF_UNDYING) { + Entity ent = pac.getEntity(mc.world); + if (!(ent instanceof PlayerEntity)) return; + if (popList == null) { + popList = new HashMap<>(); + } + if (popList.get(ent.getName().getString()) == null) { + popList.put(ent.getName().getString(), 1); + } else if (popList.get(ent.getName().getString()) != null) { + popList.put(ent.getName().getString(), popList.get(ent.getName().getString()) + 1); + } + MeteorClient.EVENT_BUS.post(TotemPopEvent.get((PlayerEntity) ent, popList.get(ent.getName().getString()))); + } + } + } + } diff --git a/src/main/java/com/genyo/addon/managers/Managers.java b/src/main/java/com/genyo/addon/managers/Managers.java index 9dce698..492bd1a 100644 --- a/src/main/java/com/genyo/addon/managers/Managers.java +++ b/src/main/java/com/genyo/addon/managers/Managers.java @@ -1,4 +1,13 @@ package com.genyo.addon.managers; +import meteordevelopment.meteorclient.MeteorClient; + public class Managers { + + public static final CombatManager COMBAT = new CombatManager(); + + public static void subscribe() { + MeteorClient.EVENT_BUS.subscribe(COMBAT); + } + } diff --git a/src/main/java/com/genyo/addon/mixin/IEntity.java b/src/main/java/com/genyo/addon/mixin/IEntity.java index b19c0de..668cc6f 100644 --- a/src/main/java/com/genyo/addon/mixin/IEntity.java +++ b/src/main/java/com/genyo/addon/mixin/IEntity.java @@ -1,4 +1,19 @@ package com.genyo.addon.mixin; +import net.minecraft.entity.Entity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3d; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(Entity.class) public interface IEntity { + @Mutable + @Accessor("pos") + void setPos(Vec3d pos); + + @Mutable + @Accessor("blockPos") + void setBlockPos(BlockPos blockPos); } diff --git a/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java b/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java index 7631b86..6540ef3 100644 --- a/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java +++ b/src/main/java/com/genyo/addon/modules/AngelSexHulkenberg.java @@ -1,6 +1,217 @@ package com.genyo.addon.modules; +import com.genyo.addon.GenyoAddon; +import com.genyo.addon.events.TotemPopEvent; +import com.genyo.addon.mixin.IEntity; +import com.genyo.addon.render.Render2DEngine; +import com.genyo.addon.render.Render3DEngine; +import com.genyo.addon.utils.MathUtil; +import com.mojang.authlib.GameProfile; +import com.mojang.blaze3d.platform.GlStateManager; +import com.mojang.blaze3d.systems.RenderSystem; +import meteordevelopment.meteorclient.events.render.Render3DEvent; +import meteordevelopment.meteorclient.settings.*; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.utils.render.color.Color; +import meteordevelopment.meteorclient.utils.render.color.SettingColor; +import meteordevelopment.orbit.EventHandler; +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.*; +import net.minecraft.client.render.entity.PlayerEntityRenderer; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.RotationAxis; +import org.jetbrains.annotations.NotNull; -public class AngelSexHulkenberg extends Module { +import java.util.concurrent.CopyOnWriteArrayList; + +public final class AngelSexHulkenberg extends Module { + + public AngelSexHulkenberg() { + super(GenyoAddon.GENYO, "angel-sex-hulkenberg", "Geci fasz csumi"); + } + + private final SettingGroup sgGeneral = settings.getDefaultGroup(); + + private final Setting mode = sgGeneral.add(new EnumSetting.Builder() + .name("Mode") + .description("Genyo") + .defaultValue(Mode.Textured) + .build() + ); + + private final Setting secondLayer = sgGeneral.add(new BoolSetting.Builder() + .name("Second Layer") + .description("nemtom") + .defaultValue(true) + .build() + ); + + private final Setting color = sgGeneral.add(new ColorSetting.Builder() + .name("Color") + .description("színcápa színcápa mondj egy színt") + .defaultValue(new Color(53, 46, 46, 37)) + .build() + ); + + private final Setting ySpeed = sgGeneral.add(new IntSetting.Builder() + .name("Y Speed") + .description("y show speed") + .defaultValue(0) + .min(-10) + .max(10) + .build() + ); + + private final Setting aSpeed = sgGeneral.add(new IntSetting.Builder() + .name("Alpha Speed") + .description("alpha show speed") + .defaultValue(5) + .min(1) + .max(100) + .build() + ); + + private final Setting rotSpeed = sgGeneral.add(new DoubleSetting.Builder() + .name("Rotation Speed") + .description("rotációs kapa") + .defaultValue(0.25) + .min(0) + .max(6) + .build() + ); + + private final CopyOnWriteArrayList popList = new CopyOnWriteArrayList<>(); + + private enum Mode { + Simple, Textured + } + + @EventHandler + public void onUpdate() { + popList.forEach(person -> person.update(popList)); + } + + @EventHandler + public void onRender(Render3DEvent event) { + MatrixStack stack = event.matrices; + + RenderSystem.enableBlend(); + RenderSystem.disableDepthTest(); + if (mode.get().equals(Mode.Simple)) RenderSystem.defaultBlendFunc(); + else RenderSystem.blendFunc(GlStateManager.SrcFactor.SRC_ALPHA, GlStateManager.DstFactor.ONE); + popList.forEach(person -> renderEntity(stack, person.player, person.getTexture(), color.get().a)); + RenderSystem.enableDepthTest(); + RenderSystem.disableBlend(); + } + + @EventHandler + @SuppressWarnings("unused") + private void onTotemPop(@NotNull TotemPopEvent e) { + if (e.entity.equals(mc.player) || mc.world == null) return; + //if (mc.world == null) return; --------- for testing + + AbstractClientPlayerEntity entity = new AbstractClientPlayerEntity(mc.world, new GameProfile(e.entity.getUuid(), e.entity.getName().getString())) { + @Override public boolean isSpectator() {return false;} + @Override public boolean isCreative() {return false;} + }; + + entity.copyPositionAndRotation(e.entity); + entity.bodyYaw = e.entity.bodyYaw; + entity.headYaw = e.entity.headYaw; + entity.handSwingProgress = e.entity.handSwingProgress; + entity.handSwingTicks = e.entity.handSwingTicks; + entity.setSneaking(e.entity.isSneaking()); + entity.limbAnimator.setSpeed(e.entity.limbAnimator.getSpeed()); + entity.limbAnimator.pos = e.entity.limbAnimator.getPos(); + popList.add(new Person(entity, ((AbstractClientPlayerEntity) e.entity).getSkinTextures().texture())); + } + + private void renderEntity(@NotNull MatrixStack matrices, @NotNull LivingEntity entity, Identifier texture, int alpha) { + PlayerEntityRenderer entityRenderer = (PlayerEntityRenderer) mc.getEntityRenderDispatcher().getRenderer((AbstractClientPlayerEntity) entity); + PlayerEntityRenderState renderState = entityRenderer.createRenderState(); + + renderState.leftPantsLegVisible = secondLayer.get(); + renderState.rightPantsLegVisible = secondLayer.get(); + renderState.leftSleeveVisible = secondLayer.get(); + renderState.rightSleeveVisible = secondLayer.get(); + renderState.jacketVisible = secondLayer.get(); + renderState.hatVisible = secondLayer.get(); + + double x = entity.getX() - mc.getEntityRenderDispatcher().camera.getPos().getX(); + double y = entity.getY() - mc.getEntityRenderDispatcher().camera.getPos().getY(); + double z = entity.getZ() - mc.getEntityRenderDispatcher().camera.getPos().getZ(); + ((IEntity) entity).setPos(entity.getPos().add(0, (double) ySpeed.get() / 50., 0)); + + matrices.push(); + matrices.translate((float) x, (float) y, (float) z); + + float yRotYaw = ((alpha / 255f) * 360f * rotSpeed.get().floatValue()); + yRotYaw = yRotYaw == 0 ? 0 : Render2DEngine.interpolateFloat(yRotYaw, yRotYaw - (((aSpeed.get() / 255f) * 360f * rotSpeed.get().floatValue())), Render3DEngine.getTickDelta()); + + matrices.multiply(RotationAxis.POSITIVE_Y.rotation(MathUtil.rad(180 - entity.bodyYaw + yRotYaw))); + prepareScale(matrices); + + float limbSpeed = Math.min(entity.limbAnimator.getSpeed(), 1f); + + entityRenderer.updateRenderState((AbstractClientPlayerEntity) entity, renderState, limbSpeed); + + BufferBuilder buffer; + if (mode.get().equals(Mode.Textured)) { + RenderSystem.setShaderTexture(0, texture); + buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE); + } else { + buffer = Tessellator.getInstance().begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION); + } + + RenderSystem.setShaderColor(color.get().r, color.get().g, color.get().b, alpha / 255f); + + entityRenderer.render(renderState, matrices, mc.getBufferBuilders().getEntityVertexConsumers(), 1); + //modelBase.render(matrices, buffer, 10, 0); + endBuilding(buffer); + RenderSystem.setShaderColor(1f, 1f, 1f, 1f); + matrices.pop(); + } + + public static void endBuilding(BufferBuilder bb) { + BuiltBuffer builtBuffer = bb.endNullable(); + if (builtBuffer != null) + BufferRenderer.drawWithGlobalProgram(builtBuffer); + } + + private static void prepareScale(@NotNull MatrixStack matrixStack) { + matrixStack.scale(-1.0F, -1.0F, 1.0F); + matrixStack.scale(1.6f, 1.8f, 1.6f); + matrixStack.translate(0.0F, -1.501F, 0.0F); + } + + private class Person { + private final AbstractClientPlayerEntity player; + private Identifier texture; + private int alpha; + + public Person(AbstractClientPlayerEntity player, Identifier texture) { + this.player = player; + alpha = color.get().a; + this.texture = texture; + } + + public void update(CopyOnWriteArrayList arrayList) { + if (alpha <= 0) { + arrayList.remove(this); + player.kill(player.getServer().getWorld(player.getWorld().getRegistryKey())); + player.remove(Entity.RemovalReason.KILLED); + player.onRemoved(); + return; + } + alpha -= aSpeed.get(); + } + + public Identifier getTexture() { + return texture; + } + } } diff --git a/src/main/java/com/genyo/addon/modules/TescoCrystal.java b/src/main/java/com/genyo/addon/modules/TescoCrystal.java index e7fd6ef..36cec8d 100644 --- a/src/main/java/com/genyo/addon/modules/TescoCrystal.java +++ b/src/main/java/com/genyo/addon/modules/TescoCrystal.java @@ -1,5 +1,6 @@ package com.genyo.addon.modules; +import com.genyo.addon.GenyoAddon; import com.google.common.util.concurrent.AtomicDouble; import it.unimi.dsi.fastutil.ints.*; import meteordevelopment.meteorclient.events.entity.EntityAddedEvent; @@ -17,6 +18,7 @@ import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; +import meteordevelopment.meteorclient.systems.modules.combat.BedAura; import meteordevelopment.meteorclient.utils.entity.DamageUtils; import meteordevelopment.meteorclient.utils.entity.EntityUtils; import meteordevelopment.meteorclient.utils.entity.Target; @@ -72,482 +74,76 @@ public class TescoCrystal extends Module { // General - private final Setting targetRange = sgGeneral.add(new DoubleSetting.Builder() - .name("target-range") - .description("Range in which to target players.") - .defaultValue(10) - .min(0) - .sliderMax(16) - .build() - ); - - private final Setting predictMovement = sgGeneral.add(new BoolSetting.Builder() - .name("predict-movement") - .description("Predicts target movement.") - .defaultValue(false) - .build() - ); - - private final Setting minDamage = sgGeneral.add(new DoubleSetting.Builder() - .name("min-damage") - .description("Minimum damage the crystal needs to deal to your target.") - .defaultValue(6) - .min(0) - .build() - ); - - private final Setting maxDamage = sgGeneral.add(new DoubleSetting.Builder() - .name("max-damage") - .description("Maximum damage crystals can deal to yourself.") - .defaultValue(6) - .range(0, 36) - .sliderMax(36) - .build() - ); - - private final Setting antiSuicide = sgGeneral.add(new BoolSetting.Builder() - .name("anti-suicide") - .description("Will not place and break crystals if they will kill you.") - .defaultValue(true) - .build() - ); - - private final Setting ignoreNakeds = sgGeneral.add(new BoolSetting.Builder() - .name("ignore-nakeds") - .description("Ignore players with no items.") - .defaultValue(false) - .build() - ); - - private final Setting rotate = sgGeneral.add(new BoolSetting.Builder() - .name("rotate") - .description("Rotates server-side towards the crystals being hit/placed.") - .defaultValue(true) - .build() - ); - - private final Setting yawStepMode = sgGeneral.add(new EnumSetting.Builder() - .name("yaw-steps-mode") - .description("When to run the yaw steps check.") - .defaultValue(YawStepMode.Break) - .visible(rotate::get) - .build() - ); - - private final Setting yawSteps = sgGeneral.add(new DoubleSetting.Builder() - .name("yaw-steps") - .description("Maximum number of degrees its allowed to rotate in one tick.") - .defaultValue(180) - .range(1, 180) - .visible(rotate::get) - .build() - ); - - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() - .name("entities") - .description("Entities to attack.") - .onlyAttackable() - .defaultValue(EntityType.PLAYER, EntityType.WARDEN, EntityType.WITHER) - .build() - ); + private final Setting targetRange = sgGeneral.add(new DoubleSetting.Builder().name("target-range").description("Range in which to target players.").defaultValue(10).min(0).sliderMax(16).build()); + private final Setting predictMovement = sgGeneral.add(new BoolSetting.Builder().name("predict-movement").description("Predicts target movement.").defaultValue(false).build()); + private final Setting minDamage = sgGeneral.add(new DoubleSetting.Builder().name("min-damage").description("Minimum damage the crystal needs to deal to your target.").defaultValue(6).min(0).build()); + private final Setting maxDamage = sgGeneral.add(new DoubleSetting.Builder().name("max-damage").description("Maximum damage crystals can deal to yourself.").defaultValue(6).range(0, 36).sliderMax(36).build()); + private final Setting antiSuicide = sgGeneral.add(new BoolSetting.Builder().name("anti-suicide").description("Will not place and break crystals if they will kill you.").defaultValue(true).build()); + private final Setting ignoreNakeds = sgGeneral.add(new BoolSetting.Builder().name("ignore-nakeds").description("Ignore players with no items.").defaultValue(false).build()); + private final Setting rotate = sgGeneral.add(new BoolSetting.Builder().name("rotate").description("Rotates server-side towards the crystals being hit/placed.").defaultValue(true).build()); + private final Setting yawStepMode = sgGeneral.add(new EnumSetting.Builder().name("yaw-steps-mode").description("When to run the yaw steps check.").defaultValue(YawStepMode.Break).visible(rotate::get).build()); + private final Setting yawSteps = sgGeneral.add(new DoubleSetting.Builder().name("yaw-steps").description("Maximum number of degrees its allowed to rotate in one tick.").defaultValue(180).range(1, 180).visible(rotate::get).build()); + private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder().name("entities").description("Entities to attack.").onlyAttackable().defaultValue(EntityType.PLAYER, EntityType.WARDEN, EntityType.WITHER).build()); // Switch - - private final Setting autoSwitch = sgSwitch.add(new EnumSetting.Builder() - .name("auto-switch") - .description("Switches to crystals in your hotbar once a target is found.") - .defaultValue(AutoSwitchMode.Normal) - .build() - ); - - private final Setting switchDelay = sgSwitch.add(new IntSetting.Builder() - .name("switch-delay") - .description("The delay in ticks to wait to break a crystal after switching hotbar slot.") - .defaultValue(0) - .min(0) - .build() - ); - - private final Setting noGapSwitch = sgSwitch.add(new BoolSetting.Builder() - .name("no-gap-switch") - .description("Won't auto switch if you're holding a gapple.") - .defaultValue(true) - .visible(() -> autoSwitch.get() == AutoSwitchMode.Normal) - .build() - ); - - private final Setting noBowSwitch = sgSwitch.add(new BoolSetting.Builder() - .name("no-bow-switch") - .description("Won't auto switch if you're holding a bow.") - .defaultValue(true) - .build() - ); - - private final Setting antiWeakness = sgSwitch.add(new BoolSetting.Builder() - .name("anti-weakness") - .description("Switches to tools with so you can break crystals with the weakness effect.") - .defaultValue(true) - .build() - ); + private final Setting autoSwitch = sgSwitch.add(new EnumSetting.Builder().name("auto-switch").description("Switches to crystals in your hotbar once a target is found.").defaultValue(AutoSwitchMode.Normal).build()); + private final Setting switchDelay = sgSwitch.add(new IntSetting.Builder().name("switch-delay").description("The delay in ticks to wait to break a crystal after switching hotbar slot.").defaultValue(0).min(0).build()); + private final Setting noGapSwitch = sgSwitch.add(new BoolSetting.Builder().name("no-gap-switch").description("Won't auto switch if you're holding a gapple.").defaultValue(true).visible(() -> autoSwitch.get() == AutoSwitchMode.Normal).build()); + private final Setting noBowSwitch = sgSwitch.add(new BoolSetting.Builder().name("no-bow-switch").description("Won't auto switch if you're holding a bow.").defaultValue(true).build()); + private final Setting antiWeakness = sgSwitch.add(new BoolSetting.Builder().name("anti-weakness").description("Switches to tools with so you can break crystals with the weakness effect.").defaultValue(true).build()); // Place - - private final Setting doPlace = sgPlace.add(new BoolSetting.Builder() - .name("place") - .description("If the CA should place crystals.") - .defaultValue(true) - .build() - ); - - public final Setting placeDelay = sgPlace.add(new IntSetting.Builder() - .name("place-delay") - .description("The delay in ticks to wait to place a crystal after it's exploded.") - .defaultValue(0) - .min(0) - .sliderMax(20) - .build() - ); - - private final Setting placeRange = sgPlace.add(new DoubleSetting.Builder() - .name("place-range") - .description("Range in which to place crystals.") - .defaultValue(4.5) - .min(0) - .sliderMax(6) - .build() - ); - - private final Setting placeWallsRange = sgPlace.add(new DoubleSetting.Builder() - .name("walls-range") - .description("Range in which to place crystals when behind blocks.") - .defaultValue(4.5) - .min(0) - .sliderMax(6) - .build() - ); - - private final Setting placement112 = sgPlace.add(new BoolSetting.Builder() - .name("1.12-placement") - .description("Uses 1.12 crystal placement.") - .defaultValue(false) - .build() - ); - - private final Setting support = sgPlace.add(new EnumSetting.Builder() - .name("support") - .description("Places a support block in air if no other position have been found.") - .defaultValue(SupportMode.Disabled) - .build() - ); - - private final Setting supportDelay = sgPlace.add(new IntSetting.Builder() - .name("support-delay") - .description("Delay in ticks after placing support block.") - .defaultValue(1) - .min(0) - .visible(() -> support.get() != SupportMode.Disabled) - .build() - ); + private final Setting doPlace = sgPlace.add(new BoolSetting.Builder().name("place").description("If the CA should place crystals.").defaultValue(true).build()); + public final Setting placeDelay = sgPlace.add(new IntSetting.Builder().name("place-delay").description("The delay in ticks to wait to place a crystal after it's exploded.").defaultValue(0).min(0).sliderMax(20).build()); + private final Setting placeRange = sgPlace.add(new DoubleSetting.Builder().name("place-range").description("Range in which to place crystals.").defaultValue(4.5).min(0).sliderMax(6).build()); + private final Setting placeWallsRange = sgPlace.add(new DoubleSetting.Builder().name("walls-range").description("Range in which to place crystals when behind blocks.").defaultValue(4.5).min(0).sliderMax(6).build()); + private final Setting placement112 = sgPlace.add(new BoolSetting.Builder().name("1.12-placement").description("Uses 1.12 crystal placement.").defaultValue(false).build()); + private final Setting support = sgPlace.add(new EnumSetting.Builder().name("support").description("Places a support block in air if no other position have been found.").defaultValue(SupportMode.Disabled).build()); + private final Setting supportDelay = sgPlace.add(new IntSetting.Builder().name("support-delay").description("Delay in ticks after placing support block.").defaultValue(1).min(0).visible(() -> support.get() != SupportMode.Disabled).build()); // Face place - - private final Setting facePlace = sgFacePlace.add(new BoolSetting.Builder() - .name("face-place") - .description("Will face-place when target is below a certain health or armor durability threshold.") - .defaultValue(true) - .build() - ); - - private final Setting facePlaceHealth = sgFacePlace.add(new DoubleSetting.Builder() - .name("face-place-health") - .description("The health the target has to be at to start face placing.") - .defaultValue(8) - .min(1) - .sliderMin(1) - .sliderMax(36) - .visible(facePlace::get) - .build() - ); - - private final Setting facePlaceDurability = sgFacePlace.add(new DoubleSetting.Builder() - .name("face-place-durability") - .description("The durability threshold percentage to be able to face-place.") - .defaultValue(2) - .min(1) - .sliderMin(1) - .sliderMax(100) - .visible(facePlace::get) - .build() - ); - - private final Setting facePlaceArmor = sgFacePlace.add(new BoolSetting.Builder() - .name("face-place-missing-armor") - .description("Automatically starts face placing when a target misses a piece of armor.") - .defaultValue(false) - .visible(facePlace::get) - .build() - ); - - private final Setting forceFacePlace = sgFacePlace.add(new KeybindSetting.Builder() - .name("force-face-place") - .description("Starts face place when this button is pressed.") - .defaultValue(Keybind.none()) - .build() - ); + private final Setting facePlace = sgFacePlace.add(new BoolSetting.Builder().name("face-place").description("Will face-place when target is below a certain health or armor durability threshold.").defaultValue(true).build()); + private final Setting facePlaceHealth = sgFacePlace.add(new DoubleSetting.Builder().name("face-place-health").description("The health the target has to be at to start face placing.").defaultValue(8).min(1).sliderMin(1).sliderMax(36).visible(facePlace::get).build()); + private final Setting facePlaceDurability = sgFacePlace.add(new DoubleSetting.Builder().name("face-place-durability").description("The durability threshold percentage to be able to face-place.").defaultValue(2).min(1).sliderMin(1).sliderMax(100).visible(facePlace::get).build()); + private final Setting facePlaceArmor = sgFacePlace.add(new BoolSetting.Builder().name("face-place-missing-armor").description("Automatically starts face placing when a target misses a piece of armor.").defaultValue(false).visible(facePlace::get).build()); + private final Setting forceFacePlace = sgFacePlace.add(new KeybindSetting.Builder().name("force-face-place").description("Starts face place when this button is pressed.").defaultValue(Keybind.none()).build()); // Break - private final Setting doBreak = sgBreak.add(new BoolSetting.Builder() - .name("break") - .description("If the CA should break crystals.") - .defaultValue(true) - .build() - ); - - private final Setting breakDelay = sgBreak.add(new IntSetting.Builder() - .name("break-delay") - .description("The delay in ticks to wait to break a crystal after it's placed.") - .defaultValue(0) - .min(0) - .sliderMax(20) - .build() - ); - - private final Setting smartDelay = sgBreak.add(new BoolSetting.Builder() - .name("smart-delay") - .description("Only breaks crystals when the target can receive damage.") - .defaultValue(false) - .build() - ); - - private final Setting breakRange = sgBreak.add(new DoubleSetting.Builder() - .name("break-range") - .description("Range in which to break crystals.") - .defaultValue(4.5) - .min(0) - .sliderMax(6) - .build() - ); - - private final Setting breakWallsRange = sgBreak.add(new DoubleSetting.Builder() - .name("walls-range") - .description("Range in which to break crystals when behind blocks.") - .defaultValue(4.5) - .min(0) - .sliderMax(6) - .build() - ); - - private final Setting onlyBreakOwn = sgBreak.add(new BoolSetting.Builder() - .name("only-own") - .description("Only breaks own crystals.") - .defaultValue(false) - .build() - ); - - private final Setting breakAttempts = sgBreak.add(new IntSetting.Builder() - .name("break-attempts") - .description("How many times to hit a crystal before stopping to target it.") - .defaultValue(2) - .sliderMin(1) - .sliderMax(5) - .build() - ); - - private final Setting ticksExisted = sgBreak.add(new IntSetting.Builder() - .name("ticks-existed") - .description("Amount of ticks a crystal needs to have lived for it to be attacked by CrystalAura.") - .defaultValue(0) - .min(0) - .build() - ); - - private final Setting attackFrequency = sgBreak.add(new IntSetting.Builder() - .name("attack-frequency") - .description("Maximum hits to do per second.") - .defaultValue(25) - .min(1) - .sliderRange(1, 30) - .build() - ); - - private final Setting fastBreak = sgBreak.add(new BoolSetting.Builder() - .name("fast-break") - .description("Ignores break delay and tries to break the crystal as soon as it's spawned in the world.") - .defaultValue(true) - .build() - ); + private final Setting doBreak = sgBreak.add(new BoolSetting.Builder().name("break").description("If the CA should break crystals.").defaultValue(true).build()); + private final Setting breakDelay = sgBreak.add(new IntSetting.Builder().name("break-delay").description("The delay in ticks to wait to break a crystal after it's placed.").defaultValue(0).min(0).sliderMax(20).build()); + private final Setting smartDelay = sgBreak.add(new BoolSetting.Builder().name("smart-delay").description("Only breaks crystals when the target can receive damage.").defaultValue(false).build()); + private final Setting breakRange = sgBreak.add(new DoubleSetting.Builder().name("break-range").description("Range in which to break crystals.").defaultValue(4.5).min(0).sliderMax(6).build()); + private final Setting breakWallsRange = sgBreak.add(new DoubleSetting.Builder().name("walls-range").description("Range in which to break crystals when behind blocks.").defaultValue(4.5).min(0).sliderMax(6).build()); + private final Setting onlyBreakOwn = sgBreak.add(new BoolSetting.Builder().name("only-own").description("Only breaks own crystals.").defaultValue(false).build()); + private final Setting breakAttempts = sgBreak.add(new IntSetting.Builder().name("break-attempts").description("How many times to hit a crystal before stopping to target it.").defaultValue(2).sliderMin(1).sliderMax(5).build()); + private final Setting ticksExisted = sgBreak.add(new IntSetting.Builder().name("ticks-existed").description("Amount of ticks a crystal needs to have lived for it to be attacked by CrystalAura.").defaultValue(0).min(0).build()); + private final Setting attackFrequency = sgBreak.add(new IntSetting.Builder().name("attack-frequency").description("Maximum hits to do per second.").defaultValue(25).min(1).sliderRange(1, 30).build()); + private final Setting fastBreak = sgBreak.add(new BoolSetting.Builder().name("fast-break").description("Ignores break delay and tries to break the crystal as soon as it's spawned in the world.").defaultValue(true).build()); // Pause - - public final Setting pauseOnUse = sgPause.add(new EnumSetting.Builder() - .name("pause-on-use") - .description("Which processes should be paused while using an item.") - .defaultValue(PauseMode.Place) - .build() - ); - - public final Setting pauseOnMine = sgPause.add(new EnumSetting.Builder() - .name("pause-on-mine") - .description("Which processes should be paused while mining a block.") - .defaultValue(PauseMode.None) - .build() - ); - - private final Setting pauseOnLag = sgPause.add(new BoolSetting.Builder() - .name("pause-on-lag") - .description("Whether to pause if the server is not responding.") - .defaultValue(true) - .build() - ); - - public final Setting> pauseModules = sgPause.add(new ModuleListSetting.Builder() - .name("pause-modules") - .description("Pauses while any of the selected modules are active.") - .defaultValue(BedAura.class) - .build() - ); - - public final Setting pauseHealth = sgPause.add(new DoubleSetting.Builder() - .name("pause-health") - .description("Pauses when you go below a certain health.") - .defaultValue(5) - .range(0,36) - .sliderRange(0,36) - .build() - ); + public final Setting pauseOnUse = sgPause.add(new EnumSetting.Builder().name("pause-on-use").description("Which processes should be paused while using an item.").defaultValue(PauseMode.Place).build()); + public final Setting pauseOnMine = sgPause.add(new EnumSetting.Builder().name("pause-on-mine").description("Which processes should be paused while mining a block.").defaultValue(PauseMode.None).build()); + private final Setting pauseOnLag = sgPause.add(new BoolSetting.Builder().name("pause-on-lag").description("Whether to pause if the server is not responding.").defaultValue(true).build()); + public final Setting> pauseModules = sgPause.add(new ModuleListSetting.Builder().name("pause-modules").description("Pauses while any of the selected modules are active.").defaultValue(BedAura.class).build()); + public final Setting pauseHealth = sgPause.add(new DoubleSetting.Builder().name("pause-health").description("Pauses when you go below a certain health.").defaultValue(5).range(0,36).sliderRange(0,36).build()); // Render - - public final Setting swingMode = sgRender.add(new EnumSetting.Builder() - .name("swing-mode") - .description("How to swing when placing.") - .defaultValue(SwingMode.Both) - .build() - ); - - private final Setting renderMode = sgRender.add(new EnumSetting.Builder() - .name("render-mode") - .description("The mode to render in.") - .defaultValue(RenderMode.Normal) - .build() - ); - - private final Setting renderPlace = sgRender.add(new BoolSetting.Builder() - .name("render-place") - .description("Renders a block overlay over the block the crystals are being placed on.") - .defaultValue(true) - .visible(() -> renderMode.get() == RenderMode.Normal) - .build() - ); - - private final Setting placeRenderTime = sgRender.add(new IntSetting.Builder() - .name("place-time") - .description("How long to render placements.") - .defaultValue(10) - .min(0) - .sliderMax(20) - .visible(() -> renderMode.get() == RenderMode.Normal && renderPlace.get()) - .build() - ); - - private final Setting renderBreak = sgRender.add(new BoolSetting.Builder() - .name("render-break") - .description("Renders a block overlay over the block the crystals are broken on.") - .defaultValue(false) - .visible(() -> renderMode.get() == RenderMode.Normal) - .build() - ); - - private final Setting breakRenderTime = sgRender.add(new IntSetting.Builder() - .name("break-time") - .description("How long to render breaking for.") - .defaultValue(13) - .min(0) - .sliderMax(20) - .visible(() -> renderMode.get() == RenderMode.Normal && renderBreak.get()) - .build() - ); - - private final Setting smoothness = sgRender.add(new IntSetting.Builder() - .name("smoothness") - .description("How smoothly the render should move around.") - .defaultValue(10) - .min(0) - .sliderMax(20) - .visible(() -> renderMode.get() == RenderMode.Smooth) - .build() - ); - - private final Setting height = sgRender.add(new DoubleSetting.Builder() - .name("height") - .description("How tall the gradient should be.") - .defaultValue(0.7) - .min(0) - .sliderMax(1) - .visible(() -> renderMode.get() == RenderMode.Gradient) - .build() - ); - - private final Setting renderTime = sgRender.add(new IntSetting.Builder() - .name("render-time") - .description("How long to render placements.") - .defaultValue(10) - .min(0) - .sliderMax(20) - .visible(() -> renderMode.get() == RenderMode.Smooth || renderMode.get() == RenderMode.Fading) - .build() - ); - - private final Setting shapeMode = sgRender.add(new EnumSetting.Builder() - .name("shape-mode") - .description("How the shapes are rendered.") - .defaultValue(ShapeMode.Both) - .visible(() -> renderMode.get() != RenderMode.None) - .build() - ); - - private final Setting sideColor = sgRender.add(new ColorSetting.Builder() - .name("side-color") - .description("The side color of the block overlay.") - .defaultValue(new SettingColor(255, 255, 255, 45)) - .visible(() -> shapeMode.get().sides() && renderMode.get() != RenderMode.None) - .build() - ); - - private final Setting lineColor = sgRender.add(new ColorSetting.Builder() - .name("line-color") - .description("The line color of the block overlay.") - .defaultValue(new SettingColor(255, 255, 255)) - .visible(() -> shapeMode.get().lines() && renderMode.get() != RenderMode.None) - .build() - ); - - private final Setting renderDamageText = sgRender.add(new BoolSetting.Builder() - .name("damage") - .description("Renders crystal damage text in the block overlay.") - .defaultValue(true) - .visible(() -> renderMode.get() != RenderMode.None) - .build() - ); - - private final Setting damageColor = sgRender.add(new ColorSetting.Builder() - .name("damage-color") - .description("The color of the damage text.") - .defaultValue(new SettingColor(255, 255, 255)) - .visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()) - .build() - ); - - private final Setting damageTextScale = sgRender.add(new DoubleSetting.Builder() - .name("damage-scale") - .description("How big the damage text should be.") - .defaultValue(1.25) - .min(1) - .sliderMax(4) - .visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()) - .build() - ); + public final Setting swingMode = sgRender.add(new EnumSetting.Builder().name("swing-mode").description("How to swing when placing.").defaultValue(SwingMode.Both).build()); + private final Setting renderMode = sgRender.add(new EnumSetting.Builder().name("render-mode").description("The mode to render in.").defaultValue(RenderMode.Normal).build()); + private final Setting renderPlace = sgRender.add(new BoolSetting.Builder().name("render-place").description("Renders a block overlay over the block the crystals are being placed on.").defaultValue(true).visible(() -> renderMode.get() == RenderMode.Normal).build()); + private final Setting placeRenderTime = sgRender.add(new IntSetting.Builder().name("place-time").description("How long to render placements.").defaultValue(10).min(0).sliderMax(20).visible(() -> renderMode.get() == RenderMode.Normal && renderPlace.get()).build()); + private final Setting renderBreak = sgRender.add(new BoolSetting.Builder().name("render-break").description("Renders a block overlay over the block the crystals are broken on.").defaultValue(false).visible(() -> renderMode.get() == RenderMode.Normal).build()); + private final Setting breakRenderTime = sgRender.add(new IntSetting.Builder().name("break-time").description("How long to render breaking for.").defaultValue(13).min(0).sliderMax(20).visible(() -> renderMode.get() == RenderMode.Normal && renderBreak.get()).build()); + private final Setting smoothness = sgRender.add(new IntSetting.Builder().name("smoothness").description("How smoothly the render should move around.").defaultValue(10).min(0).sliderMax(20).visible(() -> renderMode.get() == RenderMode.Smooth).build()); + private final Setting height = sgRender.add(new DoubleSetting.Builder().name("height").description("How tall the gradient should be.").defaultValue(0.7).min(0).sliderMax(1).visible(() -> renderMode.get() == RenderMode.Gradient).build()); + private final Setting renderTime = sgRender.add(new IntSetting.Builder().name("render-time").description("How long to render placements.").defaultValue(10).min(0).sliderMax(20).visible(() -> renderMode.get() == RenderMode.Smooth || renderMode.get() == RenderMode.Fading).build()); + private final Setting shapeMode = sgRender.add(new EnumSetting.Builder().name("shape-mode").description("How the shapes are rendered.").defaultValue(ShapeMode.Both).visible(() -> renderMode.get() != RenderMode.None).build()); + private final Setting sideColor = sgRender.add(new ColorSetting.Builder().name("side-color").description("The side color of the block overlay.").defaultValue(new SettingColor(255, 255, 255, 45)).visible(() -> shapeMode.get().sides() && renderMode.get() != RenderMode.None).build()); + private final Setting lineColor = sgRender.add(new ColorSetting.Builder().name("line-color").description("The line color of the block overlay.").defaultValue(new SettingColor(255, 255, 255)).visible(() -> shapeMode.get().lines() && renderMode.get() != RenderMode.None).build()); + private final Setting renderDamageText = sgRender.add(new BoolSetting.Builder().name("damage").description("Renders crystal damage text in the block overlay.").defaultValue(true).visible(() -> renderMode.get() != RenderMode.None).build()); + private final Setting damageColor = sgRender.add(new ColorSetting.Builder().name("damage-color").description("The color of the damage text.").defaultValue(new SettingColor(255, 255, 255)).visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()).build()); + private final Setting damageTextScale = sgRender.add(new DoubleSetting.Builder().name("damage-scale").description("How big the damage text should be.").defaultValue(1.25).min(1).sliderMax(4).visible(() -> renderMode.get() != RenderMode.None && renderDamageText.get()).build()); // Fields @@ -596,7 +192,7 @@ public class TescoCrystal extends Module { private double renderDamage; public TescoCrystal() { - super(Categories.Combat, "crystal-aura", "Automatically places and attacks crystals."); + super(GenyoAddon.GENYO, "tesco-crystal", "adasasdasdasdsadsadasdasdsadsad"); } @Override @@ -798,8 +394,7 @@ private float getBreakDamage(Entity entity, boolean checkCrystalAge) { // Check damage to targets and face place float damage = getDamageToTargets(entity.getPos(), blockPos, true, false); - boolean shouldFacePlace = shouldFacePlace(); - double minimumDamage = shouldFacePlace ? Math.min(minDamage.get(), 1.5d) : minDamage.get(); + double minimumDamage = minDamage.get(); if (damage < minimumDamage) return 0f; @@ -860,7 +455,7 @@ private void doBreak(Entity crystal) { } private boolean isValidWeaknessItem(ItemStack itemStack, Entity crystal) { - return DamageUtils.getAttackDamage(mc.player, crystal, itemStack) > 0; + return DamageUtils.getAttackDamage((LivingEntity) mc.player, (LivingEntity) crystal, itemStack) > 0; } private void attackCrystal(Entity entity) { @@ -940,8 +535,7 @@ private void doPlace() { // Check damage to targets and face place float damage = getDamageToTargets(vec3d, bp, false, !hasBlock && support.get() == SupportMode.Fast); - boolean shouldFacePlace = shouldFacePlace(); - double minimumDamage = Math.min(minDamage.get(), shouldFacePlace ? 1.5 : minDamage.get()); + double minimumDamage = Math.min(minDamage.get(), minDamage.get()); if (damage < minimumDamage) return; @@ -1021,7 +615,7 @@ private void placeCrystal(BlockHitResult result, double damage, BlockPos support FindItemResult item = InvUtils.findInHotbar(targetItem); if (!item.found()) return; - int prevSlot = mc.player.getInventory().getSelectedSlot(); + int prevSlot = mc.player.getInventory().selectedSlot; if (autoSwitch.get() != AutoSwitchMode.None && !item.isOffhand()) InvUtils.swap(item.slot(), false); @@ -1109,7 +703,7 @@ private static double distanceBetweenAngles(double alpha, double beta) { // Face place - private boolean shouldFacePlace() { + /*private boolean shouldFacePlace() { if (!facePlace.get()) return false; if (forceFacePlace.get().isPressed()) return true; @@ -1131,7 +725,7 @@ private boolean shouldFacePlace() { } return false; - } + }*/ // Others diff --git a/src/main/java/com/genyo/addon/render/Render2DEngine.java b/src/main/java/com/genyo/addon/render/Render2DEngine.java index 874b2e0..238e02b 100644 --- a/src/main/java/com/genyo/addon/render/Render2DEngine.java +++ b/src/main/java/com/genyo/addon/render/Render2DEngine.java @@ -1,4 +1,13 @@ package com.genyo.addon.render; public class Render2DEngine { + + public static double interpolate(double oldValue, double newValue, double interpolationValue) { + return (oldValue + (newValue - oldValue) * interpolationValue); + } + + public static float interpolateFloat(float oldValue, float newValue, double interpolationValue) { + return (float) interpolate(oldValue, newValue, (float) interpolationValue); + } + } diff --git a/src/main/java/com/genyo/addon/render/Render3DEngine.java b/src/main/java/com/genyo/addon/render/Render3DEngine.java index 157b29d..1e4977d 100644 --- a/src/main/java/com/genyo/addon/render/Render3DEngine.java +++ b/src/main/java/com/genyo/addon/render/Render3DEngine.java @@ -1,4 +1,11 @@ package com.genyo.addon.render; +import static meteordevelopment.meteorclient.MeteorClient.mc; + public class Render3DEngine { + + public static float getTickDelta() { + return mc.getRenderTickCounter().getTickDelta(true); + } + } diff --git a/src/main/java/com/genyo/addon/utils/MathUtil.java b/src/main/java/com/genyo/addon/utils/MathUtil.java index bd74a5a..3267b61 100644 --- a/src/main/java/com/genyo/addon/utils/MathUtil.java +++ b/src/main/java/com/genyo/addon/utils/MathUtil.java @@ -1,4 +1,13 @@ package com.genyo.addon.utils; public class MathUtil { + + public static int clamp(int num, int min, int max) { + return num < min ? min : Math.min(num, max); + } + + public static float rad(float angle) { + return (float) (angle * Math.PI / 180); + } + } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index f147bdb..8fd3b4f 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -12,6 +12,7 @@ "repo": "https://github.com/wuritz/genyo-addon" }, "icon": "assets/genyo/icon.png", + "accessWidener": "genyo.accesswidener", "environment": "client", "entrypoints": { "meteor": [ diff --git a/src/main/resources/genyo.accesswidener b/src/main/resources/genyo.accesswidener index e69de29..c541bd4 100644 --- a/src/main/resources/genyo.accesswidener +++ b/src/main/resources/genyo.accesswidener @@ -0,0 +1,26 @@ +accessWidener v1 named + +accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractTypeHandler +accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractType +accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket +accessible field net/minecraft/client/network/ClientPlayerEntity lastSprinting Z +accessible field net/minecraft/network/packet/s2c/play/PlayerPositionLookS2CPacket pitch F +accessible field net/minecraft/network/packet/s2c/play/PlayerPositionLookS2CPacket yaw F +accessible field net/minecraft/client/render/chunk/ChunkBuilder$ChunkData nonEmptyLayers Ljava/util/Set; +accessible field net/minecraft/client/render/chunk/ChunkBuilder$ChunkData occlusionGraph Lnet/minecraft/client/render/chunk/ChunkOcclusionData; +accessible field net/minecraft/entity/projectile/FishingBobberEntity CAUGHT_FISH Lnet/minecraft/entity/data/TrackedData; +accessible field net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket onGround Z +accessible field net/minecraft/network/packet/c2s/play/PlayerMoveC2SPacket pitch F +accessible field net/minecraft/network/packet/c2s/play/ChatMessageC2SPacket chatMessage Ljava/lang/String; +accessible field net/minecraft/entity/LimbAnimator pos F +accessible field net/minecraft/network/packet/s2c/play/PlayerRemoveS2CPacket profileIds Ljava/util/List; +accessible field net/minecraft/client/network/ClientPlayerInteractionManager currentBreakingProgress F +accessible field net/minecraft/client/Mouse cursorDeltaY D +accessible field net/minecraft/client/Mouse cursorDeltaX D +accessible field net/minecraft/entity/Entity hasVisualFire Z +accessible field net/minecraft/network/packet/s2c/play/GameMessageS2CPacket content Lnet/minecraft/text/Text; +accessible method net/minecraft/entity/LivingEntity tryUseTotem (Lnet/minecraft/entity/damage/DamageSource;)Z +accessible field net/minecraft/block/spawner/MobSpawnerLogic spawnDelay I +accessible class net/minecraft/client/gui/hud/InGameHud$HeartType +accessible method net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket write (Lnet/minecraft/network/PacketByteBuf;)V +accessible method net/minecraft/client/world/ClientWorld getPendingUpdateManager ()Lnet/minecraft/client/network/PendingUpdateManager; diff --git a/src/main/resources/genyo.mixins.json b/src/main/resources/genyo.mixins.json index 61bb683..0514050 100644 --- a/src/main/resources/genyo.mixins.json +++ b/src/main/resources/genyo.mixins.json @@ -5,7 +5,8 @@ "client": [ "HudRendererAccessor", "PlayerUtilsMixin", - "FriendsInjector" + "FriendsInjector", + "IEntity" ], "injectors": { "defaultRequire": 1 From 7bb49127b383d418f6cbe7a77ff3ffb2b5800312 Mon Sep 17 00:00:00 2001 From: wuritz Date: Sun, 6 Jul 2025 22:08:25 +0200 Subject: [PATCH 4/4] rossz wolt az accesswidener --- src/main/resources/genyo.accesswidener | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/resources/genyo.accesswidener b/src/main/resources/genyo.accesswidener index c541bd4..ace9554 100644 --- a/src/main/resources/genyo.accesswidener +++ b/src/main/resources/genyo.accesswidener @@ -4,8 +4,6 @@ accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket$InteractType accessible class net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket accessible field net/minecraft/client/network/ClientPlayerEntity lastSprinting Z -accessible field net/minecraft/network/packet/s2c/play/PlayerPositionLookS2CPacket pitch F -accessible field net/minecraft/network/packet/s2c/play/PlayerPositionLookS2CPacket yaw F accessible field net/minecraft/client/render/chunk/ChunkBuilder$ChunkData nonEmptyLayers Ljava/util/Set; accessible field net/minecraft/client/render/chunk/ChunkBuilder$ChunkData occlusionGraph Lnet/minecraft/client/render/chunk/ChunkOcclusionData; accessible field net/minecraft/entity/projectile/FishingBobberEntity CAUGHT_FISH Lnet/minecraft/entity/data/TrackedData; @@ -19,7 +17,6 @@ accessible field net/minecraft/client/Mouse cursorDeltaY D accessible field net/minecraft/client/Mouse cursorDeltaX D accessible field net/minecraft/entity/Entity hasVisualFire Z accessible field net/minecraft/network/packet/s2c/play/GameMessageS2CPacket content Lnet/minecraft/text/Text; -accessible method net/minecraft/entity/LivingEntity tryUseTotem (Lnet/minecraft/entity/damage/DamageSource;)Z accessible field net/minecraft/block/spawner/MobSpawnerLogic spawnDelay I accessible class net/minecraft/client/gui/hud/InGameHud$HeartType accessible method net/minecraft/network/packet/c2s/play/PlayerInteractEntityC2SPacket write (Lnet/minecraft/network/PacketByteBuf;)V