Skip to content

Commit

Permalink
Offhand Rewrite (MeteorDevelopment#3975)
Browse files Browse the repository at this point in the history
  • Loading branch information
CrytoPal authored Aug 24, 2023
1 parent c48e8d1 commit 1f42816
Showing 1 changed file with 164 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,138 +7,241 @@

import meteordevelopment.meteorclient.events.meteor.MouseButtonEvent;
import meteordevelopment.meteorclient.events.world.TickEvent;
import meteordevelopment.meteorclient.settings.BoolSetting;
import meteordevelopment.meteorclient.settings.EnumSetting;
import meteordevelopment.meteorclient.settings.Setting;
import meteordevelopment.meteorclient.settings.SettingGroup;
import meteordevelopment.meteorclient.settings.*;
import meteordevelopment.meteorclient.systems.modules.Categories;
import meteordevelopment.meteorclient.systems.modules.Module;
import meteordevelopment.meteorclient.systems.modules.Modules;
import meteordevelopment.meteorclient.utils.misc.input.KeyAction;
import meteordevelopment.meteorclient.utils.player.FindItemResult;
import meteordevelopment.meteorclient.utils.player.InvUtils;
import meteordevelopment.meteorclient.utils.player.PlayerUtils;
import meteordevelopment.orbit.EventHandler;
import net.minecraft.item.AxeItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.item.SwordItem;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.*;

import static meteordevelopment.orbit.EventPriority.HIGHEST;
import static org.lwjgl.glfw.GLFW.GLFW_MOUSE_BUTTON_RIGHT;

public class Offhand extends Module {
private final SettingGroup sgGeneral = settings.getDefaultGroup();
private final SettingGroup sgCombat = settings.createGroup("Combat");
private final SettingGroup sgTotem = settings.createGroup("Totem");

private final Setting<Item> item = sgGeneral.add(new EnumSetting.Builder<Item>()
//Combat

private final Setting<Integer> delayTicks = sgCombat.add(new IntSetting.Builder()
.name("item-switch-delay")
.description("The delay in ticks between slot movements.")
.defaultValue(0)
.min(0)
.sliderMax(20)
.build()
);
private final Setting<Item> preferreditem = sgCombat.add(new EnumSetting.Builder<Item>()
.name("item")
.description("Which item to hold in your offhand.")
.defaultValue(Item.Crystal)
.build()
);

private final Setting<Boolean> hotbar = sgGeneral.add(new BoolSetting.Builder()
private final Setting<Boolean> hotbar = sgCombat.add(new BoolSetting.Builder()
.name("hotbar")
.description("Whether to use items from your hotbar.")
.defaultValue(false)
.build()
);

private final Setting<Boolean> rightClick = sgGeneral.add(new BoolSetting.Builder()
.name("right-click")
.description("Only holds the item in your offhand when you are holding right click.")
private final Setting<Boolean> rightgapple = sgCombat.add(new BoolSetting.Builder()
.name("right-gapple")
.description("Will switch to a gapple when holding right click.(DO NOT USE WITH POTION ON)")
.defaultValue(false)
.build()
);


private final Setting<Boolean> SwordGap = sgCombat.add(new BoolSetting.Builder()
.name("sword-gapple")
.description("Will switch to a gapple when holding a sword and right click.")
.defaultValue(false)
.visible(rightgapple::get)
.build()
);

private final Setting<Boolean> swordGap = sgGeneral.add(new BoolSetting.Builder()
.name("sword-gap")
private final Setting<Boolean> alwaysSwordGap = sgCombat.add(new BoolSetting.Builder()
.name("always-gap-on-sword")
.description("Holds an Enchanted Golden Apple when you are holding a sword.")
.defaultValue(true)
.defaultValue(false)
.visible(() -> !rightgapple.get())
.build()
);

private final Setting<Boolean> crystalCa = sgGeneral.add(new BoolSetting.Builder()
.name("crystal-on-ca")
.description("Holds a crystal when you have Crystal Aura enabled.")
.defaultValue(true)

private final Setting<Boolean> alwaysPot = sgCombat.add(new BoolSetting.Builder()
.name("always-pot-on-sword")
.description("Will switch to a potion when holding a sword")
.defaultValue(false)
.visible(() -> !rightgapple.get() && !alwaysSwordGap.get())
.build()
);
private final Setting<Boolean> potionClick = sgCombat.add(new BoolSetting.Builder()
.name("sword-pot")
.description("Will switch to a potion when holding a sword and right click.")
.defaultValue(false)
.visible(() -> !rightgapple.get() && !alwaysPot.get() && !alwaysSwordGap.get() )
.build()
);

private final Setting<Boolean> crystalMine = sgGeneral.add(new BoolSetting.Builder()
.name("crystal-on-mine")
.description("Holds a crystal when you are mining.")
//Totem

private final Setting<Double> minHealth = sgTotem.add(new DoubleSetting.Builder()
.name("min-health")
.description("Will hold a totem when below this amount of health.")
.defaultValue(10)
.range(0,36)
.sliderRange(0,36)
.build()
);

private final Setting<Boolean> elytra = sgTotem.add(new BoolSetting.Builder()
.name("elytra")
.description("Will always hold a totem while flying with an elytra.")
.defaultValue(false)
.build()
);

private final Setting<Boolean> falling = sgTotem.add(new BoolSetting.Builder()
.name("falling")
.description("Will hold a totem if fall damage could kill you.")
.defaultValue(false)
.build()
);

private final Setting<Boolean> explosion = sgTotem.add(new BoolSetting.Builder()
.name("explosion")
.description("Will hold a totem when explosion damage could kill you.")
.defaultValue(true)
.build()
);


private boolean isClicking;
private boolean sentMessage;

private Item currentItem;
public boolean locked;

private int totems, ticks;

public Offhand() {
super(Categories.Combat, "offhand", "Allows you to hold specified items in your offhand.");
}

@Override
public void onActivate() {
ticks = 0;
sentMessage = false;
isClicking = false;
currentItem = item.get();
currentItem = preferreditem.get();
}

@EventHandler
private void onTick(TickEvent.Pre event) {
AutoTotem autoTotem = Modules.get().get(AutoTotem.class);
@EventHandler(priority = HIGHEST + 999)
private void onTick(TickEvent.Pre event) throws InterruptedException {
FindItemResult result = InvUtils.find(Items.TOTEM_OF_UNDYING);
totems = result.count();

// Sword Gap
if ((mc.player.getMainHandStack().getItem() instanceof SwordItem
|| mc.player.getMainHandStack().getItem() instanceof AxeItem) && swordGap.get()) currentItem = Item.EGap;
if (totems <= 0) locked = false;
else if (ticks > delayTicks.get()) {
boolean low = mc.player.getHealth() + mc.player.getAbsorptionAmount() - PlayerUtils.possibleHealthReductions(explosion.get(), falling.get()) <= minHealth.get();
boolean ely = elytra.get() && mc.player.getEquippedStack(EquipmentSlot.CHEST).getItem() == Items.ELYTRA && mc.player.isFallFlying();
FindItemResult item = InvUtils.find(itemStack -> itemStack.getItem() == currentItem.item, 0, 35);

// Ca and mining
else if ((Modules.get().isActive(CrystalAura.class) && crystalCa.get())
|| mc.interactionManager.isBreakingBlock() && crystalMine.get()) currentItem = Item.Crystal;
// Calculates Damage from Falling, Explosions + Elyta
locked = (low || ely);

else currentItem = item.get();
if (locked && mc.player.getOffHandStack().getItem() != Items.TOTEM_OF_UNDYING) {
InvUtils.move().from(result.slot()).toOffhand();
}

// Checking offhand item
if (mc.player.getOffHandStack().getItem() != currentItem.item) {
FindItemResult item = InvUtils.find(itemStack -> itemStack.getItem() == currentItem.item, hotbar.get() ? 0 : 9, 35);
ticks = 0;
return;
}
ticks++;

AutoTotem autoTotem = Modules.get().get(AutoTotem.class);

// Returns to the original Item
currentItem = preferreditem.get();

// No offhand item
if (!item.found()) {
if (!sentMessage) {
warning("Chosen item not found.");
sentMessage = true;
// Sword Gap & Right Gap
if (rightgapple.get()) {
if (!locked) {
if (SwordGap.get() && mc.player.getMainHandStack().getItem() instanceof SwordItem) {
if (isClicking) {
currentItem = Item.EGap;
}
}
if (!SwordGap.get()) {
if (isClicking) {
currentItem = Item.EGap;
}
}
}
}

// Swap to offhand
else if ((isClicking || !rightClick.get()) && !autoTotem.isLocked() && !item.isOffhand()) {
InvUtils.move().from(item.slot()).toOffhand();
sentMessage = false;
// Always Gap
else if ((mc.player.getMainHandStack().getItem() instanceof SwordItem || mc.player.getMainHandStack().getItem() instanceof AxeItem) && alwaysSwordGap.get()) currentItem = Item.EGap;

// Potion Click
else if (potionClick.get()) {
if (!locked) {
if (mc.player.getMainHandStack().getItem() instanceof SwordItem) {
if (isClicking) {
currentItem = Item.Potion;
}
}
}
}

// If not clicking, set to totem if auto totem is on
else if (!isClicking && rightClick.get()) {
if (autoTotem.isActive()) {
FindItemResult totem = InvUtils.find(itemStack -> itemStack.getItem() == Items.TOTEM_OF_UNDYING, hotbar.get() ? 0 : 9, 35);
// Always Pot
else if ((mc.player.getMainHandStack().getItem() instanceof SwordItem || mc.player.getMainHandStack().getItem() instanceof AxeItem) && alwaysPot.get()) currentItem = Item.Potion;

if (totem.found() && !totem.isOffhand()) {
InvUtils.move().from(totem.slot()).toOffhand();

else currentItem = preferreditem.get();

// Checking offhand item
if (mc.player.getOffHandStack().getItem() != currentItem.item) {
if (ticks >= delayTicks.get()) {
if (!locked) {
FindItemResult item = InvUtils.find(itemStack -> itemStack.getItem() == currentItem.item, hotbar.get() ? 0 : 9, 35);

// No offhand item
if (!item.found()) {
if (!sentMessage) {
warning("Chosen item not found.");
sentMessage = true;
}
}

// Swap to offhand
else if ((isClicking || !autoTotem.isLocked() && !item.isOffhand())) {
InvUtils.move().from(item.slot()).toOffhand();
sentMessage = false;
}
ticks = 0;
return;
}
} else {
FindItemResult empty = InvUtils.find(ItemStack::isEmpty, hotbar.get() ? 0 : 9, 35);
if (empty.found()) InvUtils.move().fromOffhand().to(empty.slot());
ticks++;
}
}
}

@EventHandler
private void onMouseButton(MouseButtonEvent event) {
// Detects if the User is right-clicking
isClicking = mc.currentScreen == null && !Modules.get().get(AutoTotem.class).isLocked() && !usableItem() && !mc.player.isUsingItem() && event.action == KeyAction.Press && event.button == GLFW_MOUSE_BUTTON_RIGHT;
}

private boolean usableItem() {
// What counts as a Usable Item
return mc.player.getMainHandStack().getItem() == Items.BOW
|| mc.player.getMainHandStack().getItem() == Items.TRIDENT
|| mc.player.getMainHandStack().getItem() == Items.CROSSBOW
Expand All @@ -147,20 +250,21 @@ private boolean usableItem() {

@Override
public String getInfoString() {
return item.get().name();
return preferreditem.get().name();
}

public enum Item {
// Items the module could put on your offhand
EGap(Items.ENCHANTED_GOLDEN_APPLE),
Gap(Items.GOLDEN_APPLE),
Crystal(Items.END_CRYSTAL),
Totem(Items.TOTEM_OF_UNDYING),
Shield(Items.SHIELD);

Shield(Items.SHIELD),
Potion(Items.POTION);
net.minecraft.item.Item item;

Item(net.minecraft.item.Item item) {
this.item = item;
}
}

}

0 comments on commit 1f42816

Please sign in to comment.