diff --git a/src/main/java/meteordevelopment/meteorclient/commands/arguments/SettingValueArgumentType.java b/src/main/java/meteordevelopment/meteorclient/commands/arguments/SettingValueArgumentType.java index e7267dce71..f391313852 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/arguments/SettingValueArgumentType.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/arguments/SettingValueArgumentType.java @@ -12,8 +12,6 @@ import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import meteordevelopment.meteorclient.settings.Setting; -import net.minecraft.command.CommandSource; -import net.minecraft.util.Identifier; import java.util.concurrent.CompletableFuture; @@ -39,6 +37,7 @@ public String parse(StringReader reader) throws CommandSyntaxException { @Override public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) { + Setting setting; try { @@ -47,11 +46,6 @@ public CompletableFuture listSuggestions(CommandContext cont return Suggestions.empty(); } - Iterable identifiers = setting.getIdentifierSuggestions(); - if (identifiers != null) { - return CommandSource.suggestIdentifiers(identifiers, builder); - } - - return CommandSource.suggestMatching(setting.getSuggestions(), builder); + return setting.buildSuggestions(builder); } } diff --git a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java index 555b73793d..06568124a1 100644 --- a/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java +++ b/src/main/java/meteordevelopment/meteorclient/commands/commands/SwarmCommand.java @@ -16,6 +16,7 @@ import meteordevelopment.meteorclient.commands.arguments.ModuleArgumentType; import meteordevelopment.meteorclient.commands.arguments.PlayerArgumentType; import meteordevelopment.meteorclient.pathing.PathManagers; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; import meteordevelopment.meteorclient.systems.modules.misc.swarm.Swarm; @@ -212,7 +213,8 @@ else if (swarm.isWorker()) { swarm.host.sendMessage(context.getInput()); } else if (swarm.isWorker()) { - Modules.get().get(InfinityMiner.class).targetBlocks.set(List.of(context.getArgument("target", BlockStateArgument.class).getBlockState().getBlock())); + // TODO: resolve + Modules.get().get(InfinityMiner.class).targetBlocks.set(new GroupSet<>(List.of(context.getArgument("target", BlockStateArgument.class).getBlockState().getBlock()))); runInfinityMiner(); } } @@ -228,8 +230,9 @@ else if (swarm.isWorker()) { swarm.host.sendMessage(context.getInput()); } else if (swarm.isWorker()) { - Modules.get().get(InfinityMiner.class).targetBlocks.set(List.of(context.getArgument("target", BlockStateArgument.class).getBlockState().getBlock())); - Modules.get().get(InfinityMiner.class).repairBlocks.set(List.of(context.getArgument("repair", BlockStateArgument.class).getBlockState().getBlock())); + // TODO: resolve + Modules.get().get(InfinityMiner.class).targetBlocks.set(new GroupSet<>(List.of(context.getArgument("target", BlockStateArgument.class).getBlockState().getBlock()))); + Modules.get().get(InfinityMiner.class).repairBlocks.set(new GroupSet<>(List.of(context.getArgument("repair", BlockStateArgument.class).getBlockState().getBlock()))); runInfinityMiner(); } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java index 34e02ab42c..19f4778d07 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/DefaultSettingsWidgetFactory.java @@ -53,8 +53,8 @@ public DefaultSettingsWidgetFactory(GuiTheme theme) { factories.put(BlockSetting.class, (table, setting) -> blockW(table, (BlockSetting) setting)); factories.put(BlockListSetting.class, (table, setting) -> blockListW(table, (BlockListSetting) setting)); factories.put(ItemSetting.class, (table, setting) -> itemW(table, (ItemSetting) setting)); - factories.put(ItemListSetting.class, (table, setting) -> itemListW(table, (ItemListSetting) setting)); - factories.put(EntityTypeListSetting.class, (table, setting) -> entityTypeListW(table, (EntityTypeListSetting) setting)); + factories.put(ItemSetSetting.class, (table, setting) -> itemListW(table, (ItemSetSetting) setting)); + factories.put(EntityTypeSetSetting.class, (table, setting) -> entityTypeListW(table, (EntityTypeSetSetting) setting)); factories.put(EnchantmentListSetting.class, (table, setting) -> enchantmentListW(table, (EnchantmentListSetting) setting)); factories.put(ModuleListSetting.class, (table, setting) -> moduleListW(table, (ModuleListSetting) setting)); factories.put(PacketListSetting.class, (table, setting) -> packetListW(table, (PacketListSetting) setting)); @@ -273,7 +273,7 @@ private void blockPosW(WTable table, BlockPosSetting setting) { } private void blockListW(WTable table, BlockListSetting setting) { - selectW(table, setting, () -> mc.setScreen(new BlockListSettingScreen(theme, setting))); + selectW(table, setting, () -> mc.setScreen(new BlockSetSettingScreen(theme, setting))); } private void itemW(WTable table, ItemSetting setting) { @@ -292,12 +292,12 @@ private void itemW(WTable table, ItemSetting setting) { reset(table, setting, () -> item.set(setting.get().getDefaultStack())); } - private void itemListW(WTable table, ItemListSetting setting) { - selectW(table, setting, () -> mc.setScreen(new ItemListSettingScreen(theme, setting))); + private void itemListW(WTable table, ItemSetSetting setting) { + selectW(table, setting, () -> mc.setScreen(new ItemSetSettingScreen(theme, setting))); } - private void entityTypeListW(WTable table, EntityTypeListSetting setting) { - selectW(table, setting, () -> mc.setScreen(new EntityTypeListSettingScreen(theme, setting))); + private void entityTypeListW(WTable table, EntityTypeSetSetting setting) { + selectW(table, setting, () -> mc.setScreen(new EntityTypeSetSettingScreen(theme, setting))); } private void enchantmentListW(WTable table, EnchantmentListSetting setting) { diff --git a/src/main/java/meteordevelopment/meteorclient/gui/GuiIcon.java b/src/main/java/meteordevelopment/meteorclient/gui/GuiIcon.java new file mode 100644 index 0000000000..d83d8c33ec --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/GuiIcon.java @@ -0,0 +1,35 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui; + +import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; +import meteordevelopment.meteorclient.utils.render.color.Color; + +import javax.annotation.Nullable; + +public class GuiIcon { + + public GuiTexture texture; + public double rotation; + public @Nullable Color color; + + public GuiIcon(GuiTexture texture, double rotation, @Nullable Color color) { + this.texture = texture; + this.rotation = rotation; + this.color = color; + } + public GuiIcon(GuiTexture texture) { + this(texture, 0, null); + } + + public GuiIcon(GuiTexture texture, double rotation) { + this(texture, rotation, null); + } + + public GuiIcon(GuiTexture texture, Color color) { + this(texture, 0, color); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java index f353ff5d09..bf1f038fc5 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/GuiTheme.java @@ -80,22 +80,27 @@ public WHorizontalSeparator horizontalSeparator() { } public abstract WVerticalSeparator verticalSeparator(); - protected abstract WButton button(String text, GuiTexture texture); + protected abstract WButton button(String text, GuiIcon icon); public WButton button(String text) { return button(text, null); } - public WButton button(GuiTexture texture) { - return button(null, texture); + public WButton button(GuiIcon icon) { + return button(null, icon); } - protected abstract WConfirmedButton confirmedButton(String text, String confirmText, GuiTexture texture); + + protected abstract WConfirmedButton confirmedButton(String text, String confirmText, GuiIcon icon); public WConfirmedButton confirmedButton(String text, String confirmText) { return confirmedButton(text, confirmText, null); } - public WConfirmedButton confirmedButton(GuiTexture texture) { - return confirmedButton(null, null, texture); + public WConfirmedButton confirmedButton(GuiIcon icon) { + return confirmedButton(null, null, icon); } + // for compatibility + final public WButton button(GuiTexture texture) { return button(null, texture.icon()); } + final public WButton confirmedButton(GuiTexture texture) { return confirmedButton(null, null, texture.icon()); } + public abstract WMinus minus(); public abstract WConfirmedMinus confirmedMinus(); public abstract WPlus plus(); diff --git a/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java b/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java index 9eca9b2945..082cd360b1 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/renderer/GuiRenderer.java @@ -8,6 +8,7 @@ import it.unimi.dsi.fastutil.Stack; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.gui.GuiIcon; import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.renderer.operations.TextOperation; import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; @@ -38,6 +39,7 @@ public class GuiRenderer { public static GuiTexture CIRCLE; public static GuiTexture TRIANGLE; + public static GuiTexture ARROWHEAD, ARROWHEAD_DOUBLE; public static GuiTexture EDIT; public static GuiTexture RESET; public static GuiTexture FAVORITE_NO, FAVORITE_YES; @@ -70,6 +72,9 @@ public static GuiTexture addTexture(Identifier id) { public static void init() { CIRCLE = addTexture(MeteorClient.identifier("textures/icons/gui/circle.png")); TRIANGLE = addTexture(MeteorClient.identifier("textures/icons/gui/triangle.png")); + ARROWHEAD = addTexture(MeteorClient.identifier("textures/icons/gui/arrowhead.png")); + ARROWHEAD_DOUBLE = addTexture(MeteorClient.identifier("textures/icons/gui/double-arrowhead.png")); + FAVORITE_YES = addTexture(MeteorClient.identifier("textures/icons/gui/triangle.png")); EDIT = addTexture(MeteorClient.identifier("textures/icons/gui/edit.png")); RESET = addTexture(MeteorClient.identifier("textures/icons/gui/reset.png")); FAVORITE_NO = addTexture(MeteorClient.identifier("textures/icons/gui/favorite_no.png")); @@ -240,6 +245,11 @@ public void rotatedQuad(double x, double y, double width, double height, double rTex.texQuad(x, y, width, height, rotation, texture.get(width, height), color); } + public void iconQuad(double x, double y, double width, double height, GuiIcon icon, Color defaultColor) { + if (icon.color != null) defaultColor = icon.color; + rotatedQuad(x, y, width, height, icon.rotation, icon.texture, defaultColor); + } + public void triangle(double x1, double y1, double x2, double y2, double x3, double y3, Color color) { r.triangle(x1, y1, x2, y2, x3, y3 ,color); } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/renderer/packer/GuiTexture.java b/src/main/java/meteordevelopment/meteorclient/gui/renderer/packer/GuiTexture.java index 424e838853..eb50ed55d7 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/renderer/packer/GuiTexture.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/renderer/packer/GuiTexture.java @@ -5,6 +5,9 @@ package meteordevelopment.meteorclient.gui.renderer.packer; +import meteordevelopment.meteorclient.gui.GuiIcon; +import meteordevelopment.meteorclient.utils.render.color.Color; + import java.util.ArrayList; import java.util.List; @@ -32,4 +35,20 @@ public TextureRegion get(double width, double height) { return closestRegion; } + + public GuiIcon icon() { + return new GuiIcon(this); + } + + public GuiIcon icon(double rotation) { + return new GuiIcon(this, rotation); + } + + public GuiIcon icon(Color color) { + return new GuiIcon(this, color); + } + + public GuiIcon icon(double rotation, Color color) { + return new GuiIcon(this, rotation, color); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockListSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockSetSettingScreen.java similarity index 78% rename from src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockListSettingScreen.java rename to src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockSetSettingScreen.java index d0309ce85b..bccf295b9e 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockListSettingScreen.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/BlockSetSettingScreen.java @@ -6,7 +6,7 @@ package meteordevelopment.meteorclient.gui.screens.settings; import meteordevelopment.meteorclient.gui.GuiTheme; -import meteordevelopment.meteorclient.gui.screens.settings.base.CollectionListSettingScreen; +import meteordevelopment.meteorclient.gui.screens.settings.base.GroupedSetSettingScreen; import meteordevelopment.meteorclient.gui.widgets.WWidget; import meteordevelopment.meteorclient.settings.BlockListSetting; import meteordevelopment.meteorclient.utils.misc.Names; @@ -17,9 +17,9 @@ import java.util.function.Predicate; -public class BlockListSettingScreen extends CollectionListSettingScreen { - public BlockListSettingScreen(GuiTheme theme, BlockListSetting setting) { - super(theme, "Select Blocks", setting, setting.get(), Registries.BLOCK); +public class BlockSetSettingScreen extends GroupedSetSettingScreen { + public BlockSetSettingScreen(GuiTheme theme, BlockListSetting setting) { + super(theme, "Select Blocks", setting, BlockListSetting.GROUPS, Registries.BLOCK); } @Override @@ -28,7 +28,7 @@ protected boolean includeValue(Block value) { return false; } - Predicate filter = ((BlockListSetting) setting).filter; + Predicate filter = setting.getFilter(); if (filter == null) return value != Blocks.AIR; return filter.test(value); @@ -36,7 +36,7 @@ protected boolean includeValue(Block value) { @Override protected WWidget getValueWidget(Block value) { - return theme.itemWithLabel(value.asItem().getDefaultStack(), Names.get(value)); + return theme.itemWithLabel(value.asItem().getDefaultStack(), Names.get(value)).color(includeValue(value) ? theme.textColor() : theme.textSecondaryColor()); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeListSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeListSettingScreen.java deleted file mode 100644 index c6399c7975..0000000000 --- a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeListSettingScreen.java +++ /dev/null @@ -1,282 +0,0 @@ -/* - * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). - * Copyright (c) Meteor Development. - */ - -package meteordevelopment.meteorclient.gui.screens.settings; - -import meteordevelopment.meteorclient.gui.GuiTheme; -import meteordevelopment.meteorclient.gui.WindowScreen; -import meteordevelopment.meteorclient.gui.utils.Cell; -import meteordevelopment.meteorclient.gui.widgets.WWidget; -import meteordevelopment.meteorclient.gui.widgets.containers.WSection; -import meteordevelopment.meteorclient.gui.widgets.containers.WTable; -import meteordevelopment.meteorclient.gui.widgets.containers.WVerticalList; -import meteordevelopment.meteorclient.gui.widgets.input.WTextBox; -import meteordevelopment.meteorclient.gui.widgets.pressable.WCheckbox; -import meteordevelopment.meteorclient.settings.EntityTypeListSetting; -import meteordevelopment.meteorclient.utils.Utils; -import meteordevelopment.meteorclient.utils.misc.Names; -import net.minecraft.entity.EntityType; -import net.minecraft.registry.Registries; -import net.minecraft.util.Pair; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; -import java.util.function.Consumer; - -public class EntityTypeListSettingScreen extends WindowScreen { - private final EntityTypeListSetting setting; - - private WVerticalList list; - private final WTextBox filter; - - private String filterText = ""; - - private WSection animals, waterAnimals, monsters, ambient, misc; - private WTable animalsT, waterAnimalsT, monstersT, ambientT, miscT; - int hasAnimal = 0, hasWaterAnimal = 0, hasMonster = 0, hasAmbient = 0, hasMisc = 0; - - public EntityTypeListSettingScreen(GuiTheme theme, EntityTypeListSetting setting) { - super(theme, "Select entities"); - this.setting = setting; - - // Filter - filter = super.add(theme.textBox("")).minWidth(400).expandX().widget(); - filter.setFocused(true); - filter.action = () -> { - filterText = filter.get().trim(); - - list.clear(); - initWidgets(); - }; - - list = super.add(theme.verticalList()).expandX().widget(); - - } - - @Override - public Cell add(W widget) { - return list.add(widget); - } - - @Override - public void initWidgets() { - hasAnimal = hasWaterAnimal = hasMonster = hasAmbient = hasMisc = 0; - - for (EntityType entityType : setting.get()) { - if (setting.filter == null || setting.filter.test(entityType)) { - switch (entityType.getSpawnGroup()) { - case CREATURE -> hasAnimal++; - case WATER_AMBIENT, WATER_CREATURE, UNDERGROUND_WATER_CREATURE, AXOLOTLS -> hasWaterAnimal++; - case MONSTER -> hasMonster++; - case AMBIENT -> hasAmbient++; - case MISC -> hasMisc++; - } - } - } - - boolean first = animals == null; - - // Animals - List> animalsE = new ArrayList<>(); - WCheckbox animalsC = theme.checkbox(hasAnimal > 0); - - animals = theme.section("Animals", animals != null && animals.isExpanded(), animalsC); - animalsC.action = () -> tableChecked(animalsE, animalsC.checked); - - Cell animalsCell = add(animals).expandX(); - animalsT = animals.add(theme.table()).expandX().widget(); - - // Water animals - List> waterAnimalsE = new ArrayList<>(); - WCheckbox waterAnimalsC = theme.checkbox(hasWaterAnimal > 0); - - waterAnimals = theme.section("Water Animals", waterAnimals != null && waterAnimals.isExpanded(), waterAnimalsC); - waterAnimalsC.action = () -> tableChecked(waterAnimalsE, waterAnimalsC.checked); - - Cell waterAnimalsCell = add(waterAnimals).expandX(); - waterAnimalsT = waterAnimals.add(theme.table()).expandX().widget(); - - // Monsters - List> monstersE = new ArrayList<>(); - WCheckbox monstersC = theme.checkbox(hasMonster > 0); - - monsters = theme.section("Monsters", monsters != null && monsters.isExpanded(), monstersC); - monstersC.action = () -> tableChecked(monstersE, monstersC.checked); - - Cell monstersCell = add(monsters).expandX(); - monstersT = monsters.add(theme.table()).expandX().widget(); - - // Ambient - List> ambientE = new ArrayList<>(); - WCheckbox ambientC = theme.checkbox(hasAmbient > 0); - - ambient = theme.section("Ambient", ambient != null && ambient.isExpanded(), ambientC); - ambientC.action = () -> tableChecked(ambientE, ambientC.checked); - - Cell ambientCell = add(ambient).expandX(); - ambientT = ambient.add(theme.table()).expandX().widget(); - - // Misc - List> miscE = new ArrayList<>(); - WCheckbox miscC = theme.checkbox(hasMisc > 0); - - misc = theme.section("Misc", misc != null && misc.isExpanded(), miscC); - miscC.action = () -> tableChecked(miscE, miscC.checked); - - Cell miscCell = add(misc).expandX(); - miscT = misc.add(theme.table()).expandX().widget(); - - Consumer> entityTypeForEach = entityType -> { - if (setting.filter == null || setting.filter.test(entityType)) { - switch (entityType.getSpawnGroup()) { - case CREATURE -> { - animalsE.add(entityType); - addEntityType(animalsT, animalsC, entityType); - } - case WATER_AMBIENT, WATER_CREATURE, UNDERGROUND_WATER_CREATURE, AXOLOTLS -> { - waterAnimalsE.add(entityType); - addEntityType(waterAnimalsT, waterAnimalsC, entityType); - } - case MONSTER -> { - monstersE.add(entityType); - addEntityType(monstersT, monstersC, entityType); - } - case AMBIENT -> { - ambientE.add(entityType); - addEntityType(ambientT, ambientC, entityType); - } - case MISC -> { - miscE.add(entityType); - addEntityType(miscT, miscC, entityType); - } - } - } - }; - - // Sort all entities - if (filterText.isEmpty()) { - Registries.ENTITY_TYPE.forEach(entityTypeForEach); - } else { - List, Integer>> entities = new ArrayList<>(); - Registries.ENTITY_TYPE.forEach(entity -> { - int words = Utils.searchInWords(Names.get(entity), filterText); - int diff = Utils.searchLevenshteinDefault(Names.get(entity), filterText, false); - - if (words > 0 || diff < Names.get(entity).length() / 2) entities.add(new Pair<>(entity, -diff)); - }); - entities.sort(Comparator.comparingInt(value -> -value.getRight())); - for (Pair, Integer> pair : entities) entityTypeForEach.accept(pair.getLeft()); - } - - if (animalsT.cells.isEmpty()) list.cells.remove(animalsCell); - if (waterAnimalsT.cells.isEmpty()) list.cells.remove(waterAnimalsCell); - if (monstersT.cells.isEmpty()) list.cells.remove(monstersCell); - if (ambientT.cells.isEmpty()) list.cells.remove(ambientCell); - if (miscT.cells.isEmpty()) list.cells.remove(miscCell); - - if (first) { - int totalCount = (hasWaterAnimal + waterAnimals.cells.size() + monsters.cells.size() + ambient.cells.size() + misc.cells.size()) / 2; - - if (totalCount <= 20) { - if (!animalsT.cells.isEmpty()) animals.setExpanded(true); - if (!waterAnimalsT.cells.isEmpty()) waterAnimals.setExpanded(true); - if (!monstersT.cells.isEmpty()) monsters.setExpanded(true); - if (!ambientT.cells.isEmpty()) ambient.setExpanded(true); - if (!miscT.cells.isEmpty()) misc.setExpanded(true); - } - else { - if (!animalsT.cells.isEmpty()) animals.setExpanded(false); - if (!waterAnimalsT.cells.isEmpty()) waterAnimals.setExpanded(false); - if (!monstersT.cells.isEmpty()) monsters.setExpanded(false); - if (!ambientT.cells.isEmpty()) ambient.setExpanded(false); - if (!miscT.cells.isEmpty()) misc.setExpanded(false); - } - } - } - - private void tableChecked(List> entityTypes, boolean checked) { - boolean changed = false; - - for (EntityType entityType : entityTypes) { - if (checked) { - setting.get().add(entityType); - changed = true; - } else { - if (setting.get().remove(entityType)) { - changed = true; - } - } - } - - if (changed) { - list.clear(); - initWidgets(); - setting.onChanged(); - } - } - - private void addEntityType(WTable table, WCheckbox tableCheckbox, EntityType entityType) { - table.add(theme.label(Names.get(entityType))); - - WCheckbox a = table.add(theme.checkbox(setting.get().contains(entityType))).expandCellX().right().widget(); - a.action = () -> { - if (a.checked) { - setting.get().add(entityType); - switch (entityType.getSpawnGroup()) { - case CREATURE -> { - if (hasAnimal == 0) tableCheckbox.checked = true; - hasAnimal++; - } - case WATER_AMBIENT, WATER_CREATURE, UNDERGROUND_WATER_CREATURE, AXOLOTLS -> { - if (hasWaterAnimal == 0) tableCheckbox.checked = true; - hasWaterAnimal++; - } - case MONSTER -> { - if (hasMonster == 0) tableCheckbox.checked = true; - hasMonster++; - } - case AMBIENT -> { - if (hasAmbient == 0) tableCheckbox.checked = true; - hasAmbient++; - } - case MISC -> { - if (hasMisc == 0) tableCheckbox.checked = true; - hasMisc++; - } - } - } else { - if (setting.get().remove(entityType)) { - switch (entityType.getSpawnGroup()) { - case CREATURE -> { - hasAnimal--; - if (hasAnimal == 0) tableCheckbox.checked = false; - } - case WATER_AMBIENT, WATER_CREATURE, UNDERGROUND_WATER_CREATURE, AXOLOTLS -> { - hasWaterAnimal--; - if (hasWaterAnimal == 0) tableCheckbox.checked = false; - } - case MONSTER -> { - hasMonster--; - if (hasMonster == 0) tableCheckbox.checked = false; - } - case AMBIENT -> { - hasAmbient--; - if (hasAmbient == 0) tableCheckbox.checked = false; - } - case MISC -> { - hasMisc--; - if (hasMisc == 0) tableCheckbox.checked = false; - } - } - } - } - - setting.onChanged(); - }; - - table.row(); - } -} diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeSetSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeSetSettingScreen.java new file mode 100644 index 0000000000..18e86c2f32 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/EntityTypeSetSettingScreen.java @@ -0,0 +1,41 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui.screens.settings; + +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.screens.settings.base.GroupedSetSettingScreen; +import meteordevelopment.meteorclient.gui.widgets.WWidget; +import meteordevelopment.meteorclient.settings.EntityTypeSetSetting; +import meteordevelopment.meteorclient.utils.misc.Names; +import net.minecraft.entity.EntityType; +import net.minecraft.registry.Registries; + +import java.util.function.Predicate; + +public class EntityTypeSetSettingScreen extends GroupedSetSettingScreen, EntityTypeSetSetting> { + + public EntityTypeSetSettingScreen(GuiTheme theme, EntityTypeSetSetting setting) { + super(theme, "Select Entities", setting, EntityTypeSetSetting.GROUPS, Registries.ENTITY_TYPE); + } + + @Override + protected boolean includeValue(EntityType value) { + Predicate> filter = setting.getFilter(); + return filter == null || filter.test(value); + } + + @Override + protected WWidget getValueWidget(EntityType value) { + return theme.label(Names.get(value)).color(includeValue(value) ? theme.textColor() : theme.textSecondaryColor()); + } + + protected String[] getValueNames(EntityType value) { + return new String[]{ + Names.get(value), + Registries.ENTITY_TYPE.getId(value).toString() + }; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemListSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemSetSettingScreen.java similarity index 62% rename from src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemListSettingScreen.java rename to src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemSetSettingScreen.java index 3e58d7d70f..72212d4b06 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemListSettingScreen.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/ItemSetSettingScreen.java @@ -6,9 +6,9 @@ package meteordevelopment.meteorclient.gui.screens.settings; import meteordevelopment.meteorclient.gui.GuiTheme; -import meteordevelopment.meteorclient.gui.screens.settings.base.CollectionListSettingScreen; +import meteordevelopment.meteorclient.gui.screens.settings.base.GroupedSetSettingScreen; import meteordevelopment.meteorclient.gui.widgets.WWidget; -import meteordevelopment.meteorclient.settings.ItemListSetting; +import meteordevelopment.meteorclient.settings.ItemSetSetting; import meteordevelopment.meteorclient.utils.misc.Names; import net.minecraft.item.Item; import net.minecraft.item.Items; @@ -16,22 +16,21 @@ import java.util.function.Predicate; -public class ItemListSettingScreen extends CollectionListSettingScreen { - public ItemListSettingScreen(GuiTheme theme, ItemListSetting setting) { - super(theme, "Select Items", setting, setting.get(), Registries.ITEM); +public class ItemSetSettingScreen extends GroupedSetSettingScreen { + public ItemSetSettingScreen(GuiTheme theme, ItemSetSetting setting) { + super(theme, "Select Items", setting, ItemSetSetting.GROUPS, Registries.ITEM); } @Override protected boolean includeValue(Item value) { - Predicate filter = ((ItemListSetting) setting).filter; + Predicate filter = setting.getFilter(); if (filter != null && !filter.test(value)) return false; return value != Items.AIR; } @Override - protected WWidget getValueWidget(Item value) { - return theme.itemWithLabel(value.getDefaultStack()); + protected WWidget getValueWidget(Item value) { return theme.itemWithLabel(value.getDefaultStack(), Names.get(value)).color(includeValue(value) ? theme.textColor() : theme.textSecondaryColor()); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/base/GroupedSetSettingScreen.java b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/base/GroupedSetSettingScreen.java new file mode 100644 index 0000000000..443abf16b2 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/gui/screens/settings/base/GroupedSetSettingScreen.java @@ -0,0 +1,344 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.gui.screens.settings.base; + +import meteordevelopment.meteorclient.MeteorClient; +import meteordevelopment.meteorclient.gui.GuiTheme; +import meteordevelopment.meteorclient.gui.WindowScreen; +import meteordevelopment.meteorclient.gui.renderer.GuiRenderer; +import meteordevelopment.meteorclient.gui.utils.Cell; +import meteordevelopment.meteorclient.gui.widgets.WWidget; +import meteordevelopment.meteorclient.gui.widgets.containers.WContainer; +import meteordevelopment.meteorclient.gui.widgets.containers.WTable; +import meteordevelopment.meteorclient.gui.widgets.input.WTextBox; +import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; +import meteordevelopment.meteorclient.gui.widgets.pressable.WPressable; +import meteordevelopment.meteorclient.settings.GroupedSetSetting; +import meteordevelopment.meteorclient.settings.groups.IGroup; +import meteordevelopment.meteorclient.utils.render.color.Color; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; + +public abstract class GroupedSetSettingScreen> extends WindowScreen { + protected final S setting; + private final Iterable registry; + private final GroupedSetSetting.Groups groups; + + public GroupedSetSettingScreen(GuiTheme theme, String title, S setting, GroupedSetSetting.Groups groups, Iterable registry) { + super(theme, title); + + this.registry = registry; + this.setting = setting; + this.groups = groups; + } + + protected final class Context { + private WTable table; + private String filterText = ""; + private GroupedSetSetting.Groups.Group expanded = null; + private GroupedSetSetting.Groups.Group beingEdited = null; + private IGroup.Group> source; + private Runnable reload; + } + + private final Context ctx = new Context(); + + private void createWidgets(WindowScreen root, Context ctx) { + // Filter + WTextBox filter = root.add(theme.textBox("")).minWidth(400).expandX().widget(); + filter.setFocused(true); + + ctx.table = root.add(theme.table()).expandX().widget(); + + filter.action = () -> { + ctx.filterText = filter.get().trim(); + + ctx.table.clear(); + initTable(ctx); + }; + + initTable(ctx); + } + + @Override + public void initWidgets() { + this.ctx.source = this.setting.get(); + this.ctx.reload = this::reload; + createWidgets(this, this.ctx); + } + + private void initTable(Context ctx) { + + List list = new ArrayList<>(groups.getAll().stream().map(ItemUnion::new).toList()); + + registry.forEach((t) -> list.add(new ItemUnion(t))); + + // Left (all) + WTable left = abc(ctx, list, true, t -> { + addValue(ctx, t); + + if (t.t != null) { + T v = getAdditionalValue(t.t); + if (v != null) addValue(ctx, t); + } + }); + + if (!left.cells.isEmpty()) ctx.table.add(theme.verticalSeparator()).expandWidgetY(); + + list.clear(); + list.addAll(ctx.source.getGroups().stream().map(ItemUnion::new).toList()); + ctx.source.getImmediate().forEach((t) -> list.add(new ItemUnion(t))); + + // Right (selected) + WTable right = abc(ctx, list, false, t -> { + removeValue(ctx, t); + + if (t.t != null) { + T v = getAdditionalValue(t.t); + if (v != null) removeValue(ctx, t); + } + }); + + postWidgets(left, right); + } + + private WWidget groupLabel(GroupedSetSetting.Groups.Group s) { + Color color = entireGroupExcluded(s) ? new Color(200, 100, 10) : Color.ORANGE; + if (s.showIcon.get()) return theme.itemWithLabel(s.icon.get().asItem().getDefaultStack(), "@"+s.name.get()).color(color); + else return theme.label(" @"+s.name.get()).color(color); + } + + private void addGroupTransferButton(Context ctx, WTable table,GroupedSetSetting.Groups.Group g) { + if (ctx.source.getImmediate().containsAll(g.getAllMatching(setting.getFilter()))) { + table.add(theme.button(GuiRenderer.ARROWHEAD_DOUBLE.icon(180, Color.RED))).right().top().widget().action = () -> { + ctx.source.removeAll(g.getAll()); + invalidateTable(ctx); + }; + } else { + table.add(theme.button(GuiRenderer.ARROWHEAD_DOUBLE.icon(Color.CYAN))).right().top().widget().action = () -> { + ctx.source.addAll(g.getAll()); + invalidateTable(ctx); + }; + } + } + + private void addTransferButton(Context ctx, WTable table, T t) { + if (ctx.source.getImmediate().contains(t)) { + table.add(theme.button(GuiRenderer.ARROWHEAD.icon(180, Color.RED))).right().top().widget().action = () -> { + ctx.source.remove(t); + invalidateTable(ctx); + }; + } else { + table.add(theme.button(GuiRenderer.ARROWHEAD.icon(Color.ORANGE))).right().top().widget().action = () -> { + ctx.source.add(t); + invalidateTable(ctx); + }; + } + } + + private WTable abc(Context ctx, Iterable iterable, boolean isLeft, Consumer buttonAction) { + // Create + Cell cell = ctx.table.add(theme.table()).top(); + WTable table = cell.widget(); + + // Sort + Predicate predicate = isLeft + ? v -> Boolean.TRUE.equals(v.map( + t -> this.includeValue(t) && !ctx.source.getImmediate().contains(t), + s -> !entireGroupExcluded(s) && !ctx.source.getGroups().contains(s) && s != ctx.beingEdited)) + : v -> true; + + Iterable sorted = SortingHelper.sort(iterable, predicate, v -> v.map(this::getValueNames, s -> new String[]{"@"+s.name.get()}), ctx.filterText); + + sorted.forEach(v -> { + + WTable buttons = theme.table(); + + if (v.s == null) { + table.add(getValueWidget(v.t)); + table.add(buttons).right(); + } else { + GroupedSetSetting.Groups.Group s = v.s; + + WTable header = table.add(theme.table()).widget(); + + boolean e = ctx.expanded == s; + + WButton expand = header.add(theme.button(GuiRenderer.TRIANGLE.icon(e ? 0 : -90))).widget(); + expand.action = () -> { + ctx.expanded = e ? null : s; + ctx.reload.run(); + }; + + header.add(groupLabel(s)); + + // Recursive editing is confusing + if (ctx.beingEdited == null) { + WButton edit = buttons.add(theme.button(GuiRenderer.EDIT)).right().top().widget(); + edit.action = () -> MeteorClient.mc.setScreen(new EditListGroupScreen(theme, s, () -> { + invalidateTable(ctx); + ctx.reload.run(); + })); + } + + addGroupTransferButton(ctx, buttons, s); + + table.add(buttons).right(); + + if (e) { + for (GroupedSetSetting.Groups.Group inc : s.getGroups()) { + table.row(); + + WTable label = theme.table(); + label.add(theme.label(" -> ")); + label.add(groupLabel(inc)); + table.add(label); + + addGroupTransferButton(ctx, table, inc); + } + + Iterable subitems = SortingHelper.sortWithPriority(s.getImmediate(), (t)->true, this::getValueNames, "", (T a, T b) -> includeValue(a) == includeValue(b) ? 0 : includeValue(a) ? -1 : 1); + + subitems.forEach(t -> { + table.row(); + + WTable label = theme.table(); + label.add(theme.label(" -> ")); + label.add(getValueWidget(t)); + table.add(label); + + addTransferButton(ctx, table, t); + }); + } + + } + + WPressable button = buttons.add(isLeft ? theme.plus() : theme.minus()).expandCellX().right().top().widget(); + button.action = () -> buttonAction.accept(v); + + table.row(); + }); + + if (!table.cells.isEmpty()) cell.expandX(); + + return table; + } + + private boolean entireGroupExcluded(GroupedSetSetting.Groups.Group s) { + return !s.anyMatch(this::includeValue); + } + + protected void invalidateTable(Context ctx) { + ctx.table.clear(); + initTable(ctx); + } + + protected void addValue(Context ctx, ItemUnion value) { + if (value.t != null) { + ctx.source.add(value.t); + setting.onChanged(); + invalidateTable(ctx); + } else if (value.s != null) { + ctx.source.add(value.s); + setting.onChanged(); + invalidateTable(ctx); + } + } + + protected void removeValue(Context ctx, ItemUnion value) { + if (value.t != null) { + ctx.source.remove(value.t); + setting.onChanged(); + invalidateTable(ctx); + } else if (value.s != null) { + ctx.source.remove(value.s); + setting.onChanged(); + invalidateTable(ctx); + } + } + + protected void postWidgets(WTable left, WTable right) {} + + protected boolean includeValue(T value) { + return true; + } + + protected abstract WWidget getValueWidget(T value); + + protected abstract String[] getValueNames(T value); + + protected T getAdditionalValue(T value) { + return null; + } + + protected class ItemUnion { + private final T t; + private final GroupedSetSetting.Groups.Group s; + + public ItemUnion(T t) { + this.s = null; + this.t = t; + } + + public ItemUnion(GroupedSetSetting.Groups.Group s) { + this.s = s; + this.t = null; + } + + public R map(Function a, Function.Group, R> b) { + if (t != null) return a.apply(t); + else if (s != null) return b.apply(s); + return null; + } + } + + public class EditListGroupScreen extends WindowScreen { + + private final GroupedSetSetting.Groups.Group value; + private final Runnable reload; + + private final Context ctx = new Context(); + + private WContainer container; + + public EditListGroupScreen(GuiTheme theme, GroupedSetSetting.Groups.Group value, Runnable reload) { + super(theme, "Editing Group"); + + this.value = value == null ? setting.createGroup("new-group") : value; + this.reload = reload; + this.value.builtin = false; + + GroupedSetSettingScreen.this.setting.set(GroupedSetSettingScreen.this.setting.get()); + } + + @Override + public void initWidgets() { + container = add(theme.verticalList()).expandX().minWidth(400).padTop(4).widget(); + container.add(theme.settings(value.settings)).expandX().padBottom(4); + + add(theme.horizontalSeparator("Contents")).expandX().padBottom(4); + + this.ctx.source = value; + this.ctx.reload = this::reload; + this.ctx.beingEdited = value; + createWidgets(this, this.ctx); + } + + @Override + protected void onClosed() { + this.reload.run(); + } + + @Override + public void tick() { + value.settings.tick(container, theme); + } + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java index c82be6a451..950a31bd9b 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/MeteorGuiTheme.java @@ -6,6 +6,7 @@ package meteordevelopment.meteorclient.gui.themes.meteor; import meteordevelopment.meteorclient.gui.DefaultSettingsWidgetFactory; +import meteordevelopment.meteorclient.gui.GuiIcon; import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.WidgetScreen; import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; @@ -206,13 +207,13 @@ public WVerticalSeparator verticalSeparator() { } @Override - protected WButton button(String text, GuiTexture texture) { - return w(new WMeteorButton(text, texture)); + protected WButton button(String text, GuiIcon icon) { + return w(new WMeteorButton(text, icon)); } @Override - protected WConfirmedButton confirmedButton(String text, String confirmText, GuiTexture texture) { - return w(new WMeteorConfirmedButton(text, confirmText, texture)); + protected WConfirmedButton confirmedButton(String text, String confirmText, GuiIcon icon) { + return w(new WMeteorConfirmedButton(text, confirmText, icon)); } @Override diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorButton.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorButton.java index 3dafe58034..abb9727243 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorButton.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorButton.java @@ -5,15 +5,15 @@ package meteordevelopment.meteorclient.gui.themes.meteor.widgets.pressable; +import meteordevelopment.meteorclient.gui.GuiIcon; import meteordevelopment.meteorclient.gui.renderer.GuiRenderer; -import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; import meteordevelopment.meteorclient.gui.themes.meteor.MeteorGuiTheme; import meteordevelopment.meteorclient.gui.themes.meteor.MeteorWidget; import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; public class WMeteorButton extends WButton implements MeteorWidget { - public WMeteorButton(String text, GuiTexture texture) { - super(text, texture); + public WMeteorButton(String text, GuiIcon icon) { + super(text, icon); } @Override @@ -28,7 +28,7 @@ protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, doub } else { double ts = theme.textHeight(); - renderer.quad(x + width / 2 - ts / 2, y + pad, ts, ts, texture, theme.textColor.get()); + renderer.iconQuad(x + width / 2 - ts / 2, y + pad, ts, ts, icon, theme.textColor.get()); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorConfirmedButton.java b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorConfirmedButton.java index 57b92c801d..d3d8e51fa4 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorConfirmedButton.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/themes/meteor/widgets/pressable/WMeteorConfirmedButton.java @@ -5,17 +5,17 @@ package meteordevelopment.meteorclient.gui.themes.meteor.widgets.pressable; +import meteordevelopment.meteorclient.gui.GuiIcon; import meteordevelopment.meteorclient.gui.renderer.GuiRenderer; import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; import meteordevelopment.meteorclient.gui.themes.meteor.MeteorGuiTheme; import meteordevelopment.meteorclient.gui.themes.meteor.MeteorWidget; -import meteordevelopment.meteorclient.gui.widgets.pressable.WButton; import meteordevelopment.meteorclient.gui.widgets.pressable.WConfirmedButton; import meteordevelopment.meteorclient.utils.render.color.Color; public class WMeteorConfirmedButton extends WConfirmedButton implements MeteorWidget { - public WMeteorConfirmedButton(String text, String confirmText, GuiTexture texture) { - super(text, confirmText, texture); + public WMeteorConfirmedButton(String text, String confirmText, GuiIcon icon) { + super(text, confirmText, icon); } @Override @@ -36,7 +36,7 @@ protected void onRender(GuiRenderer renderer, double mouseX, double mouseY, doub } else { double ts = theme.textHeight(); - renderer.quad(x + width / 2 - ts / 2, y + pad, ts, ts, texture, fg); + renderer.iconQuad(x + width / 2 - ts / 2, y + pad, ts, ts, icon, fg); } } } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WItemWithLabel.java b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WItemWithLabel.java index cd7b4decfc..33ef90a751 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/widgets/WItemWithLabel.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/widgets/WItemWithLabel.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.gui.widgets.containers.WHorizontalList; import meteordevelopment.meteorclient.utils.misc.Names; +import meteordevelopment.meteorclient.utils.render.color.Color; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.entity.effect.StatusEffectUtil; @@ -24,6 +25,8 @@ public class WItemWithLabel extends WHorizontalList { private WItem item; private WLabel label; + private Color color; + public WItemWithLabel(ItemStack itemStack, String name) { this.itemStack = itemStack; this.name = name; @@ -33,6 +36,7 @@ public WItemWithLabel(ItemStack itemStack, String name) { public void init() { item = add(theme.item(itemStack)).widget(); label = add(theme.label(name + getStringToAppend())).widget(); + if (color != null) label.color(color); } private String getStringToAppend() { @@ -61,6 +65,11 @@ public void set(ItemStack itemStack) { label.set(name + getStringToAppend()); } + public WItemWithLabel color(Color color) { + this.color = color; + return this; + } + public String getLabelText() { return label == null ? name : label.get(); } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WButton.java b/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WButton.java index f740c6ec95..f21b648d2d 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WButton.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WButton.java @@ -5,17 +5,17 @@ package meteordevelopment.meteorclient.gui.widgets.pressable; -import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; +import meteordevelopment.meteorclient.gui.GuiIcon; public abstract class WButton extends WPressable { protected String text; protected double textWidth; - protected GuiTexture texture; + protected GuiIcon icon; - public WButton(String text, GuiTexture texture) { + public WButton(String text, GuiIcon icon) { this.text = text; - this.texture = texture; + this.icon = icon; if (text == null) instantTooltips = true; } diff --git a/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WConfirmedButton.java b/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WConfirmedButton.java index b4c535cba5..8009fa6877 100644 --- a/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WConfirmedButton.java +++ b/src/main/java/meteordevelopment/meteorclient/gui/widgets/pressable/WConfirmedButton.java @@ -5,6 +5,7 @@ package meteordevelopment.meteorclient.gui.widgets.pressable; +import meteordevelopment.meteorclient.gui.GuiIcon; import meteordevelopment.meteorclient.gui.renderer.packer.GuiTexture; import net.minecraft.client.gui.Click; @@ -13,8 +14,8 @@ public abstract class WConfirmedButton extends WButton { protected boolean pressedOnce = false; protected String confirmText; - public WConfirmedButton(String text, String confirmText, GuiTexture texture) { - super(text, texture); + public WConfirmedButton(String text, String confirmText, GuiIcon icon) { + super(text, icon); this.confirmText = confirmText; } diff --git a/src/main/java/meteordevelopment/meteorclient/pathing/BaritoneSettings.java b/src/main/java/meteordevelopment/meteorclient/pathing/BaritoneSettings.java index 8294edaa12..63c62d4d62 100644 --- a/src/main/java/meteordevelopment/meteorclient/pathing/BaritoneSettings.java +++ b/src/main/java/meteordevelopment/meteorclient/pathing/BaritoneSettings.java @@ -180,31 +180,34 @@ else if (value instanceof Color) { .build() ); } - else if (value instanceof List) { - Type listType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; - Type type = ((ParameterizedType) listType).getActualTypeArguments()[0]; - - if (type == Block.class) { - sgBlockLists.add(new BlockListSetting.Builder() - .name(setting.getName()) - .description(getDescription(setting.getName())) - .defaultValue((List) setting.defaultValue) - .onChanged(blockList -> setting.value = blockList) - .onModuleActivated(blockListSetting -> blockListSetting.set((List) setting.value)) - .build() - ); - } - else if (type == Item.class) { - sgItemLists.add(new ItemListSetting.Builder() - .name(setting.getName()) - .description(getDescription(setting.getName())) - .defaultValue((List) setting.defaultValue) - .onChanged(itemList -> setting.value = itemList) - .onModuleActivated(itemListSetting -> itemListSetting.set((List) setting.value)) - .build() - ); - } - } + + // TODO: resolve + +// else if (value instanceof List) { +// Type listType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0]; +// Type type = ((ParameterizedType) listType).getActualTypeArguments()[0]; +// +// if (type == Block.class) { +// sgBlockLists.add(new BlockListSetting.Builder() +// .name(setting.getName()) +// .description(getDescription(setting.getName())) +// .defaultValue((List) setting.defaultValue) +// .onChanged(blockList -> setting.value = blockList) +// .onModuleActivated(blockListSetting -> blockListSetting.set((List) setting.value)) +// .build() +// ); +// } +// else if (type == Item.class) { +// sgItemLists.add(new ItemSetSetting.Builder() +// .name(setting.getName()) +// .description(getDescription(setting.getName())) +// .defaultValue((List) setting.defaultValue) +// .onChanged(itemList -> setting.value = itemList) +// .onModuleActivated(itemListSetting -> itemListSetting.set((List) setting.value)) +// .build() +// ); +// } +// } } } catch (IllegalAccessException e) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/AbstractCollectionSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/AbstractCollectionSetting.java new file mode 100644 index 0000000000..d545cdb328 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/AbstractCollectionSetting.java @@ -0,0 +1,65 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + + +import com.mojang.brigadier.Message; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; +import net.minecraft.command.CommandSource; +import net.minecraft.util.Identifier; +import net.minecraft.util.Pair; + +import java.util.Iterator; +import java.util.Locale; +import java.util.concurrent.CompletableFuture; +import java.util.function.Consumer; + +public abstract class AbstractCollectionSetting extends Setting { + public AbstractCollectionSetting(String name, String description, T defaultValue, Consumer onChanged, Consumer> onModuleActivated, IVisible visible) { + super(name, description, defaultValue, onChanged, onModuleActivated, visible); + } + + protected String[] components(String value) { + return value.split(","); + } + + @Override + public CompletableFuture buildSuggestions(SuggestionsBuilder builder) { + String given = builder.getInput().substring(builder.getStart()); + + String[] components = components(given); + + if (components.length == 0) return builder.buildFuture(); + + String last = components[components.length - 1]; + + last = last.trim(); + + Iterable identifiers = getIdentifierSuggestions(); + + builder = builder.createOffset(builder.getStart() + given.length() - last.length()); + SuggestionsBuilder builderDuplicatedDueToArbitraryLambdaCaptureRestrictions = builder; + + if (identifiers != null) { + CommandSource.forEachMatching(identifiers, last, id -> id, id -> builderDuplicatedDueToArbitraryLambdaCaptureRestrictions.suggest(id.toString())); + return builderDuplicatedDueToArbitraryLambdaCaptureRestrictions.buildFuture(); + } + + Iterable suggestions = getSuggestions(); + + if (suggestions != null) { + for(String s : suggestions) { + if (CommandSource.shouldSuggest(last, s.toLowerCase(Locale.ROOT))) { + builderDuplicatedDueToArbitraryLambdaCaptureRestrictions.suggest(s); + } + } + } + + return builderDuplicatedDueToArbitraryLambdaCaptureRestrictions.buildFuture(); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java index 5d49ac76dd..bdf439f02e 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/BlockListSetting.java @@ -5,93 +5,93 @@ package meteordevelopment.meteorclient.settings; +import meteordevelopment.meteorclient.settings.groups.GroupSet; +import meteordevelopment.meteorclient.systems.modules.render.Xray; import net.minecraft.block.Block; -import net.minecraft.nbt.NbtCompound; +import net.minecraft.block.Blocks; +import net.minecraft.item.Items; import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; import net.minecraft.nbt.NbtString; import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; -import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; -public class BlockListSetting extends Setting> { - public final Predicate filter; +public class BlockListSetting extends GroupedSetSetting { - public BlockListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, Predicate filter, IVisible visible) { - super(name, description, defaultValue, onChanged, onModuleActivated, visible); - - this.filter = filter; + public BlockListSetting(String name, String description, GroupSet.Group> defaultValue, Consumer.Group>> onChanged, Consumer.Group>>> onModuleActivated, Predicate filter, IVisible visible) { + super(name, description, defaultValue, filter, onChanged, onModuleActivated, visible); } @Override - public void resetImpl() { - value = new ArrayList<>(defaultValue); + public Block parseItem(String str) { + Block block = parseId(Registries.BLOCK, str); + if (block != null && (filter == null || filter.test(block))) return block; + return null; } @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List blocks = new ArrayList<>(values.length); - - try { - for (String value : values) { - Block block = parseId(Registries.BLOCK, value); - if (block != null && (filter == null || filter.test(block))) blocks.add(block); - } - } catch (Exception ignored) {} - - return blocks; + public NbtElement itemToNbt(Block block) { + return NbtString.of(Registries.BLOCK.getId(block).toString()); } @Override - protected boolean isValueValid(List value) { - return true; + public Block itemFromNbt(NbtElement e) { + Block block = Registries.BLOCK.get(Identifier.of(e.asString().orElse(""))); + if (filter == null || filter.test(block)) return block; + return null; } - @Override - public Iterable getIdentifierSuggestions() { - return Registries.BLOCK.getIds(); - } + public static final Groups GROUPS = new Groups<>(); @Override - protected NbtCompound save(NbtCompound tag) { - NbtList valueTag = new NbtList(); - for (Block block : get()) { - valueTag.add(NbtString.of(Registries.BLOCK.getId(block).toString())); - } - tag.put("value", valueTag); - - return tag; + protected Groups groups() { + return GROUPS; } @Override - protected List load(NbtCompound tag) { - get().clear(); - - NbtList valueTag = tag.getListOrEmpty("value"); - for (NbtElement tagI : valueTag) { - Block block = Registries.BLOCK.get(Identifier.of(tagI.asString().orElse(""))); - - if (filter == null || filter.test(block)) get().add(block); - } - - return get(); + protected Registry suggestRegistry() { + return Registries.BLOCK; } - public static class Builder extends SettingBuilder, BlockListSetting> { + public static class Builder extends SettingBuilder.Group>, BlockListSetting> { private Predicate filter; public Builder() { - super(new ArrayList<>(0)); + super(new GroupSet<>()); + } + + public Builder defaultValue(Collection defaults) { + if (defaultValue == null) + return defaultValue(defaults != null ? new GroupSet<>(defaults) : new GroupSet<>()); + defaultValue.addAll(defaults); + return this; } public Builder defaultValue(Block... defaults) { - return defaultValue(defaults != null ? Arrays.asList(defaults) : new ArrayList<>()); + if (defaultValue == null) + return defaultValue(defaults != null ? new GroupSet<>(Arrays.asList(defaults)) : new GroupSet<>()); + defaultValue.addAll(Arrays.asList(defaults)); + return this; + } + + @SafeVarargs + public final Builder defaultGroups(Groups.Group... defaults) { + List.Group> groups = null; + + if (defaults != null) + groups = Arrays.stream(defaults).filter(g -> g.isOf(GROUPS)).toList(); + + if (defaultValue == null) + return defaultValue(groups != null ? new GroupSet<>(null, groups) : new GroupSet<>()); + + if (groups != null) defaultValue.addAllGroups(groups); + return this; } public Builder filter(Predicate filter) { @@ -104,4 +104,24 @@ public BlockListSetting build() { return new BlockListSetting(name, description, defaultValue, onChanged, onModuleActivated, filter, visible); } } + + // These are just for testing + public static Groups.Group ORES, DIRTS, SANDS, STONES, TERRAIN; + static { + ORES = GROUPS.builtin("ores", Items.DIAMOND_ORE) + .items(Xray.ORES).get(); + DIRTS = GROUPS.builtin("dirt", Items.DIRT) + .items(Blocks.DIRT, Blocks.GRASS_BLOCK, Blocks.DIRT_PATH, Blocks.PODZOL, Blocks.COARSE_DIRT, Blocks.CLAY) + .get(); + SANDS = GROUPS.builtin("sand", Items.SAND) + .items(Blocks.SAND, Blocks.RED_SAND, Blocks.GRAVEL) + .get(); + STONES = GROUPS.builtin("stone", Items.STONE) + .items(Blocks.STONE, Blocks.DEEPSLATE, Blocks.NETHERRACK, Blocks.SANDSTONE, Blocks.TUFF, Blocks.BASALT, + Blocks.ANDESITE, Blocks.DIORITE, Blocks.GRANITE, Blocks.BLACKSTONE, Blocks.CALCITE) + .get(); + TERRAIN = GROUPS.builtin("terrain", Items.GRASS_BLOCK) + .include(STONES, DIRTS, SANDS) + .get(); + } } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java index 1726463c57..3282ed7e5c 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ColorListSetting.java @@ -14,7 +14,7 @@ import java.util.List; import java.util.function.Consumer; -public class ColorListSetting extends Setting> { +public class ColorListSetting extends AbstractCollectionSetting> { public ColorListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java index e56565df17..96ba4ab99e 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/EnchantmentListSetting.java @@ -23,7 +23,7 @@ import java.util.function.Consumer; import java.util.stream.Collectors; -public class EnchantmentListSetting extends Setting>> { +public class EnchantmentListSetting extends AbstractCollectionSetting>> { public EnchantmentListSetting(String name, String description, Set> defaultValue, Consumer>> onChanged, Consumer>>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java deleted file mode 100644 index b716b4c219..0000000000 --- a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeListSetting.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). - * Copyright (c) Meteor Development. - */ - -package meteordevelopment.meteorclient.settings; - -import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; -import meteordevelopment.meteorclient.utils.entity.EntityUtils; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.SpawnGroup; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.function.Consumer; -import java.util.function.Predicate; - -public class EntityTypeListSetting extends Setting>> { - public final Predicate> filter; - private List suggestions; - private final static List groups = List.of("animal", "wateranimal", "monster", "ambient", "misc"); - - public EntityTypeListSetting(String name, String description, Set> defaultValue, Consumer>> onChanged, Consumer>>> onModuleActivated, IVisible visible, Predicate> filter) { - super(name, description, defaultValue, onChanged, onModuleActivated, visible); - - this.filter = filter; - } - - @Override - public void resetImpl() { - value = new ObjectOpenHashSet<>(defaultValue); - } - - @Override - protected Set> parseImpl(String str) { - String[] values = str.split(","); - Set> entities = new ObjectOpenHashSet<>(values.length); - - try { - for (String value : values) { - EntityType entity = parseId(Registries.ENTITY_TYPE, value); - if (entity != null) entities.add(entity); - else { - String lowerValue = value.trim().toLowerCase(); - if (!groups.contains(lowerValue)) continue; - - for (EntityType entityType : Registries.ENTITY_TYPE) { - if (filter != null && !filter.test(entityType)) continue; - - switch (lowerValue) { - case "animal" -> { - if (entityType.getSpawnGroup() == SpawnGroup.CREATURE) entities.add(entityType); - } - case "wateranimal" -> { - if (entityType.getSpawnGroup() == SpawnGroup.WATER_AMBIENT - || entityType.getSpawnGroup() == SpawnGroup.WATER_CREATURE - || entityType.getSpawnGroup() == SpawnGroup.UNDERGROUND_WATER_CREATURE - || entityType.getSpawnGroup() == SpawnGroup.AXOLOTLS) entities.add(entityType); - } - case "monster" -> { - if (entityType.getSpawnGroup() == SpawnGroup.MONSTER) entities.add(entityType); - } - case "ambient" -> { - if (entityType.getSpawnGroup() == SpawnGroup.AMBIENT) entities.add(entityType); - } - case "misc" -> { - if (entityType.getSpawnGroup() == SpawnGroup.MISC) entities.add(entityType); - } - } - } - } - } - } catch (Exception ignored) {} - - return entities; - } - - @Override - protected boolean isValueValid(Set> value) { - return true; - } - - @Override - public List getSuggestions() { - if (suggestions == null) { - suggestions = new ArrayList<>(groups); - for (EntityType entityType : Registries.ENTITY_TYPE) { - if (filter == null || filter.test(entityType)) suggestions.add(Registries.ENTITY_TYPE.getId(entityType).toString()); - } - } - - return suggestions; - } - - @Override - public NbtCompound save(NbtCompound tag) { - NbtList valueTag = new NbtList(); - for (EntityType entityType : get()) { - valueTag.add(NbtString.of(Registries.ENTITY_TYPE.getId(entityType).toString())); - } - tag.put("value", valueTag); - - return tag; - } - - @Override - public Set> load(NbtCompound tag) { - get().clear(); - - NbtList valueTag = tag.getListOrEmpty("value"); - for (NbtElement tagI : valueTag) { - EntityType type = Registries.ENTITY_TYPE.get(Identifier.of(tagI.asString().orElse(""))); - if (filter == null || filter.test(type)) get().add(type); - } - - return get(); - } - - public static class Builder extends SettingBuilder>, EntityTypeListSetting> { - private Predicate> filter; - - public Builder() { - super(new ObjectOpenHashSet<>(0)); - } - - public Builder defaultValue(EntityType... defaults) { - return defaultValue(defaults != null ? new ObjectOpenHashSet<>(defaults) : new ObjectOpenHashSet<>(0)); - } - - public Builder onlyAttackable() { - filter = EntityUtils::isAttackable; - return this; - } - - public Builder filter(Predicate> filter){ - this.filter = filter; - return this; - } - - @Override - public EntityTypeListSetting build() { - return new EntityTypeListSetting(name, description, defaultValue, onChanged, onModuleActivated, visible, filter); - } - } -} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeSetSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeSetSetting.java new file mode 100644 index 0000000000..59ee673839 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/EntityTypeSetSetting.java @@ -0,0 +1,103 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + +import meteordevelopment.meteorclient.settings.groups.GroupSet; +import meteordevelopment.meteorclient.utils.entity.EntityUtils; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.SpawnGroup; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtString; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class EntityTypeSetSetting extends GroupedSetSetting> { + public static Groups> GROUPS = new Groups<>(); + + public EntityTypeSetSetting(String name, String description, GroupSet, Groups>.Group> defaultValue, Predicate> filter, Consumer, Groups>.Group>> onChanged, Consumer, Groups>.Group>>> onModuleActivated, IVisible visible) { + super(name, description, defaultValue, filter, onChanged, onModuleActivated, visible); + } + + @Override + public EntityType parseItem(String str) { + return parseId(Registries.ENTITY_TYPE, str); + } + + @Override + public NbtElement itemToNbt(EntityType entityType) { + return NbtString.of(Registries.ENTITY_TYPE.getId(entityType).toString()); + } + + @Override + public EntityType itemFromNbt(NbtElement e) { + return Registries.ENTITY_TYPE.get(Identifier.of(e.asString().orElse(""))); + } + + @Override + protected Groups> groups() { + return GROUPS; + } + + @Override + public void buildSuggestions(List to) { + for (EntityType entityType : Registries.ENTITY_TYPE) { + if (filter == null || filter.test(entityType)) to.add(Registries.ENTITY_TYPE.getId(entityType).toString()); + } + } + + public static class Builder extends SettingBuilder, Groups>.Group>, EntityTypeSetSetting> { + private Predicate> filter; + + public Builder() { + super(new GroupSet<>()); + } + + public Builder defaultValue(EntityType... defaults) { + return defaultValue(defaults != null ? new GroupSet<>(Arrays.asList(defaults)) : new GroupSet<>()); + } + + public Builder onlyAttackable() { + filter = EntityUtils::isAttackable; + return this; + } + + public Builder filter(Predicate> filter){ + this.filter = filter; + return this; + } + + @Override + public EntityTypeSetSetting build() { + return new EntityTypeSetSetting(name, description, defaultValue, filter, onChanged, onModuleActivated, visible); + } + } + + static Groups>.Group ANIMAL, WATER_ANIMAL, MONSTER, AMBIENT, MISC; + + static { + ANIMAL = GROUPS.dynamic("animals").get(); + WATER_ANIMAL = GROUPS.dynamic("water-animals").get(); + MONSTER = GROUPS.dynamic("monsters").get(); + AMBIENT = GROUPS.dynamic("ambient").get(); + MISC = GROUPS.dynamic("misc").get(); + + for (EntityType entityType : Registries.ENTITY_TYPE) { + if (entityType.getSpawnGroup() == SpawnGroup.CREATURE) ANIMAL.add(entityType); + if (entityType.getSpawnGroup() == SpawnGroup.MONSTER) MONSTER.add(entityType); + if (entityType.getSpawnGroup() == SpawnGroup.AMBIENT) AMBIENT.add(entityType); + if (entityType.getSpawnGroup() == SpawnGroup.MISC) MISC.add(entityType); + if (entityType.getSpawnGroup() == SpawnGroup.WATER_AMBIENT + || entityType.getSpawnGroup() == SpawnGroup.WATER_CREATURE + || entityType.getSpawnGroup() == SpawnGroup.UNDERGROUND_WATER_CREATURE + || entityType.getSpawnGroup() == SpawnGroup.AXOLOTLS) WATER_ANIMAL.add(entityType); + } + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/GroupedSetSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/GroupedSetSetting.java new file mode 100644 index 0000000000..b6a24e7749 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/GroupedSetSetting.java @@ -0,0 +1,374 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + +import meteordevelopment.meteorclient.settings.groups.GroupSet; +import meteordevelopment.meteorclient.settings.groups.SetGroup; +import meteordevelopment.meteorclient.settings.groups.SetGroupEnumeration; +import meteordevelopment.meteorclient.utils.Utils; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtList; +import net.minecraft.nbt.NbtString; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import java.util.*; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +public abstract class GroupedSetSetting extends AbstractCollectionSetting.Group>> { + + protected Predicate filter; + + private List suggestions; + + public GroupedSetSetting(String name, String description, GroupSet.Group> defaultValue, Predicate filter, Consumer.Group>> onChanged, Consumer.Group>>> onModuleActivated, IVisible visible) { + super(name, description, defaultValue, onChanged, onModuleActivated, visible); + this.filter = filter; + } + + abstract public T parseItem(String str); + + abstract public NbtElement itemToNbt(T t); + abstract public T itemFromNbt(NbtElement e); + + abstract protected Groups groups(); + long version = -1; + + public Groups.Group createGroup(String name) { + return groups().builder(name).get(); + } + + protected void buildSuggestions(List to) + { + Registry registry = suggestRegistry(); + for (Identifier id : registry.getIds()) { + if (filter == null || filter.test(registry.get(id))) to.add(id.toString()); + } + } + protected Registry suggestRegistry() { return null; } + + @Override + public GroupSet.Group> get() { + return value; + } + + public Predicate getFilter() { + return filter; + } + + @Override + public boolean set(GroupSet.Group> o) { + if (value == null) { + value = new GroupSet<>(); + value.enumeration = groups(); + value.setIncludeCondition(filter); + } + value.set(o); + onChanged(); + return true; + } + + @Override + protected void resetImpl() { + set(defaultValue); + } + + @Override + protected GroupSet.Group> parseImpl(String str) { + GroupSet.Group> list = new GroupSet<>(); + list.enumeration = groups(); + + String[] values = str.split(","); + + try { + for (String value : values) { + value = value.trim(); + Groups.Group group = null; + + if (value.startsWith("@")) { + group = groups().get(value.substring(1)); + } + + if (group != null) { + list.add(group); + continue; + } + + T item = parseItem(value); + + if (item != null) list.add(item); + } + } catch (Exception ignored) {} + + return list; + } + + @Override + protected boolean isValueValid(GroupSet.Group> value) { + return true; + } + + @Override + final protected NbtCompound save(NbtCompound tag) { + NbtList groupsTag = new NbtList(); + + // this does duplicate the contents of all groups into the config of every setting, however this is + // necessary for copy/paste to be able to share the complete config + for (Groups.Group g : groups().GROUPS.values()) if (!g.builtin) groupsTag.add(g.toTag(this::itemToNbt)); + tag.put("groups", groupsTag); + + NbtList direct = new NbtList(); + value.getImmediate().stream().map(this::itemToNbt).forEach(direct::add); + + tag.put("direct", direct); + + NbtList include = new NbtList(); + value.getGroups().stream().map((g) -> NbtString.of(g.internalName)).forEach(direct::add); + + tag.put("include", include); + + return tag; + } + + @Override + final protected GroupSet.Group> load(NbtCompound tag) { + tag.getListOrEmpty("groups").forEach(el -> el.asCompound().ifPresent(t -> groups().fromTag(t, this::itemFromNbt))); + + value.clear(); + + value.addAll(tag.getListOrEmpty("direct").stream().map(this::itemFromNbt).filter(Objects::nonNull).toList()); + value.addAllGroups(tag.getListOrEmpty("include").stream().map(NbtElement::asString).filter(Optional::isPresent).map(o -> groups().get(o.get())).toList()); + + return value; + } + + public void invalidateSuggestions() { + suggestions = null; + } + + @Override + final public Iterable getIdentifierSuggestions() { + return null; + } + + @Override + final public List getSuggestions() { + if (suggestions == null || groups().getVersion() != version) { + version = groups().getVersion(); + + suggestions = new ArrayList<>(groups().GROUPS.size()); + groups().GROUPS.forEach((_1, v)-> suggestions.add("@" + v.internalName)); + buildSuggestions(suggestions); + } + + return suggestions; + } + + static final public class Groups extends SetGroupEnumeration { + Map GROUPS = new HashMap<>(); + + public Groups.Group get(String name) { + return GROUPS.get(name.toUpperCase()); + } + + public Collection getAll() { + return GROUPS.values(); + } + + public class GroupBuilder { + + private Group g; + + public GroupBuilder(String name) { + g = new Group(name); + } + + public GroupBuilder(String name, Item icon) { + g = new Group(name); + g.icon.set(icon); + g.showIcon.set(true); + } + + private GroupBuilder builtin() { + g.builtin = true; + return this; + } + + private GroupBuilder dynamic() { + g.builtin = true; + g.dynamic = true; + return this; + } + + @SafeVarargs + public final GroupBuilder items(T... of) { + g.addAll(Arrays.asList(of)); + return this; + } + + @SafeVarargs + public final GroupBuilder include(Group... of) { + g.addAllGroups(Arrays.asList(of)); + return this; + } + + public GroupBuilder items(Collection of) { + g.addAll(of); + return this; + } + + public GroupBuilder include(Collection of) { + g.addAllGroups(of); + return this; + } + + public Group get() { + GROUPS.put(g.internalName.toUpperCase(), g); + Group w = g; + g = null; + return w; + } + } + + protected GroupBuilder builtin(String name) { + return new GroupBuilder(name).builtin(); + } + + protected GroupBuilder builtin(String name, Item icon) { + return new GroupBuilder(name, icon).builtin(); + } + + protected GroupBuilder dynamic(String name) { + return new GroupBuilder(name).dynamic(); + } + + protected GroupBuilder dynamic(String name, Item icon) { + return new GroupBuilder(name, icon).builtin(); + } + + public GroupBuilder builder(String name) { + return new GroupBuilder(name); + } + + public GroupBuilder builder(String name, Item icon) { + return new GroupBuilder(name, icon); + } + + public Group fromTag(NbtCompound tag, Function itemFromNbt) { + return new Group(tag, itemFromNbt); + } + + public class Group extends SetGroup { + public boolean builtin; // will not be saved to config + public boolean dynamic; // cannot be modified through config + + public Settings settings = new Settings(); + public SettingGroup sg = settings.getDefaultGroup(); + + private String internalName; + + public Setting name = sg.add(new StringSetting.Builder() + .name("name") + .description("the name of the group") + .onChanged(this::changeName) + .filter(Utils::nameFilter) + .build() + ); + + public Setting showIcon = sg.add(new BoolSetting.Builder() + .name("show-icon") + .description("don't show an icon") + .defaultValue(false) + .build() + ); + + public Setting icon = sg.add(new ItemSetting.Builder() + .name("icon") + .description("item to use as icon in list") + .defaultValue(Items.NETHER_STAR) + .visible(showIcon::get) + .build() + ); + + private void changeName(String v) { + if (v.equals(internalName)) return; + + // this should never happen + if (internalName == null) internalName = "_group" + hashCode(); + + Group other = GROUPS.get(v.toUpperCase()); + if (other == this) { + internalName = v; + return; + } + if (other != null) { + name.set(internalName); + } else { + GROUPS.remove(internalName.toUpperCase()); + GROUPS.put(v.toUpperCase(), this); + } + } + + private Group(String name) + { + super(Groups.this); + + internalName = name; + this.name.set(name); + } + + private Group(NbtCompound tag, Function itemFromNbt) + { + super(Groups.this); + fromTag(tag, itemFromNbt); + } + + public NbtCompound toTag(Function itemToNbt) { + NbtCompound tag = new NbtCompound(); + tag.putString("name", internalName); + tag.put("icon", Identifier.CODEC, Registries.ITEM.getId(icon.get())); + + NbtList d = new NbtList(); + immediate.forEach((t) -> d.add(itemToNbt.apply(t))); + + NbtList i = new NbtList(); + include.forEach((g) -> i.add(NbtString.of(g.internalName))); + + tag.put("direct", d); + tag.put("include", i); + return tag; + } + + public Group fromTag(NbtCompound tag, Function itemFromNbt) { + String name = tag.getString("name", null); + if (name == null) return null; + + this.name.set(name); + this.icon.set(tag.get("item", Identifier.CODEC).map(Registries.ITEM::get).orElse(Items.NETHER_STAR)); + + this.immediate.addAll(tag.getListOrEmpty("direct").stream().map(itemFromNbt).toList()); + this.include.addAll(tag.getListOrEmpty("include").stream().map(NbtElement::asString) + .filter(Optional::isPresent).map(Optional::get).map(String::toUpperCase).map((s) -> { + if (GROUPS.containsKey(s)) return GROUPS.get(s); + return GROUPS.put(s, builder(s).get()); + }).toList()); + + if (internalName == null) this.name.set(String.format("group%d", hashCode())); + + return this; + } + } + } + + +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java deleted file mode 100644 index 89da126639..0000000000 --- a/src/main/java/meteordevelopment/meteorclient/settings/ItemListSetting.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). - * Copyright (c) Meteor Development. - */ - -package meteordevelopment.meteorclient.settings; - -import net.minecraft.item.Item; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.nbt.NbtElement; -import net.minecraft.nbt.NbtList; -import net.minecraft.nbt.NbtString; -import net.minecraft.registry.Registries; -import net.minecraft.util.Identifier; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Consumer; -import java.util.function.Predicate; - -public class ItemListSetting extends Setting> { - public final Predicate filter; - private final boolean bypassFilterWhenSavingAndLoading; - - public ItemListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible, Predicate filter, boolean bypassFilterWhenSavingAndLoading) { - super(name, description, defaultValue, onChanged, onModuleActivated, visible); - - this.filter = filter; - this.bypassFilterWhenSavingAndLoading = bypassFilterWhenSavingAndLoading; - } - - @Override - protected List parseImpl(String str) { - String[] values = str.split(","); - List items = new ArrayList<>(values.length); - - try { - for (String value : values) { - Item item = parseId(Registries.ITEM, value); - if (item != null && (filter == null || filter.test(item))) items.add(item); - } - } catch (Exception ignored) {} - - return items; - } - - @Override - public void resetImpl() { - value = new ArrayList<>(defaultValue); - } - - @Override - protected boolean isValueValid(List value) { - return true; - } - - @Override - public Iterable getIdentifierSuggestions() { - return Registries.ITEM.getIds(); - } - - @Override - public NbtCompound save(NbtCompound tag) { - NbtList valueTag = new NbtList(); - for (Item item : get()) { - if (bypassFilterWhenSavingAndLoading || (filter == null || filter.test(item))) valueTag.add(NbtString.of(Registries.ITEM.getId(item).toString())); - } - tag.put("value", valueTag); - - return tag; - } - - @Override - public List load(NbtCompound tag) { - get().clear(); - - NbtList valueTag = tag.getListOrEmpty("value"); - for (NbtElement tagI : valueTag) { - Item item = Registries.ITEM.get(Identifier.of(tagI.asString().orElse(""))); - - if (bypassFilterWhenSavingAndLoading || (filter == null || filter.test(item))) get().add(item); - } - - return get(); - } - - public static class Builder extends SettingBuilder, ItemListSetting> { - private Predicate filter; - private boolean bypassFilterWhenSavingAndLoading; - - public Builder() { - super(new ArrayList<>(0)); - } - - public Builder defaultValue(Item... defaults) { - return defaultValue(defaults != null ? Arrays.asList(defaults) : new ArrayList<>()); - } - - public Builder filter(Predicate filter) { - this.filter = filter; - return this; - } - - public Builder bypassFilterWhenSavingAndLoading() { - this.bypassFilterWhenSavingAndLoading = true; - return this; - } - - @Override - public ItemListSetting build() { - return new ItemListSetting(name, description, defaultValue, onChanged, onModuleActivated, visible, filter, bypassFilterWhenSavingAndLoading); - } - } -} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ItemSetSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ItemSetSetting.java new file mode 100644 index 0000000000..16dd421af1 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/ItemSetSetting.java @@ -0,0 +1,144 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings; + +import meteordevelopment.meteorclient.settings.groups.GroupSet; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtElement; +import net.minecraft.nbt.NbtString; +import net.minecraft.registry.Registries; +import net.minecraft.registry.Registry; +import net.minecraft.util.Identifier; + +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.function.Consumer; +import java.util.function.Predicate; + +public class ItemSetSetting extends GroupedSetSetting { + + public static final Groups GROUPS = new Groups<>(); + + // TODO: resolve this (used in AutoSmelter) + private final boolean bypassFilterWhenSavingAndLoading; + + public ItemSetSetting(String name, String description, GroupSet.Group> defaultValue, Consumer.Group>> onChanged, Consumer.Group>>> onModuleActivated, IVisible visible, Predicate filter, boolean bypassFilterWhenSavingAndLoading) { + super(name, description, defaultValue, filter, onChanged, onModuleActivated, visible); + + this.bypassFilterWhenSavingAndLoading = bypassFilterWhenSavingAndLoading; + } + + @Override + public Item parseItem(String str) { + Item item = parseId(Registries.ITEM, str); + if (item != null && (filter == null || filter.test(item))) return item; + return null; + } + + @Override + public NbtElement itemToNbt(Item item) { + return NbtString.of(Registries.ITEM.getId(item).toString()); + } + + @Override + public Item itemFromNbt(NbtElement e) { + return Registries.ITEM.get(Identifier.of(e.asString().orElse(""))); + } + + @Override + protected Groups groups() { + return GROUPS; + } + + @Override + protected Registry suggestRegistry() { + return Registries.ITEM; + } + + public static class Builder extends SettingBuilder.Group>, ItemSetSetting> { + private Predicate filter = null; + private boolean bypass = false; + + public Builder() { + super(new GroupSet<>()); + } + + public Builder defaultValue(Collection defaults) { + if (defaultValue == null) + return defaultValue(defaults != null ? new GroupSet<>(defaults) : new GroupSet<>()); + defaultValue.addAll(defaults); + return this; + } + + public Builder defaultValue(Item... defaults) { + if (defaultValue == null) + return defaultValue(defaults != null ? new GroupSet<>(Arrays.asList(defaults)) : new GroupSet<>()); + defaultValue.addAll(Arrays.asList(defaults)); + return this; + } + + @SafeVarargs + public final Builder defaultGroups(Groups.Group... defaults) { + List.Group> groups = null; + + if (defaults != null) + groups = Arrays.stream(defaults).filter(g -> g.isOf(GROUPS)).toList(); + + if (defaultValue == null) + return defaultValue(groups != null ? new GroupSet<>(null, groups) : new GroupSet<>()); + + if (groups != null) defaultValue.addAllGroups(groups); + return this; + } + + public Builder filter(Predicate filter) { + this.filter = filter; + return this; + } + + @Override + public ItemSetSetting build() { + return new ItemSetSetting(name, description, defaultValue, onChanged, onModuleActivated, visible, filter, bypass); + } + } + + // these are just for UI testing, they are not necessarily good ones to have + public static Groups.Group FOOD, AXES, PICKAXES, SWORDS, HOES, TOOLS, TOOLS_STRICT, HELMETS, CHESTPLATES, LEGGINGS, BOOTS, ARMOR; + static { + + FOOD = GROUPS.builtin("food-all", Items.APPLE) + .items(Registries.ITEM.stream().filter(i -> i.getComponents().get(DataComponentTypes.FOOD) != null).toList()) + .get(); + + TOOLS_STRICT = GROUPS.builtin("tools-all", Items.GOLDEN_AXE) + .items(Registries.ITEM.stream().filter(i -> i.getComponents().get(DataComponentTypes.TOOL) != null).toList()) + .get(); + + PICKAXES = GROUPS.builtin("picks", Items.IRON_PICKAXE) + .items(Items.NETHERITE_PICKAXE, Items.NETHERITE_PICKAXE, Items.NETHERITE_PICKAXE, Items.NETHERITE_PICKAXE, Items.NETHERITE_PICKAXE, Items.NETHERITE_PICKAXE) + .get(); + + AXES = GROUPS.builtin("axes", Items.IRON_AXE) + .items(Items.WOODEN_AXE, Items.STONE_AXE, Items.IRON_AXE, Items.GOLDEN_AXE, Items.DIAMOND_AXE, Items.NETHERITE_AXE) + .get(); + + SWORDS = GROUPS.builtin("swords", Items.IRON_SWORD) + .items(Items.WOODEN_SWORD, Items.STONE_SWORD, Items.IRON_SWORD, Items.GOLDEN_SWORD, Items.DIAMOND_SWORD, Items.NETHERITE_SWORD) + .get(); + + HOES = GROUPS.builtin("hoes", Items.IRON_HOE) + .items(Items.WOODEN_HOE, Items.STONE_HOE, Items.IRON_HOE, Items.GOLDEN_HOE, Items.DIAMOND_HOE, Items.NETHERITE_HOE) + .get(); + + TOOLS = GROUPS.builtin("tools", Items.DIAMOND_AXE) + .items(Items.SHEARS, Items.FLINT_AND_STEEL) + .include(PICKAXES, AXES, HOES) + .get(); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java index 6000407ca4..63f0bd2dcb 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ModuleListSetting.java @@ -16,7 +16,7 @@ import java.util.List; import java.util.function.Consumer; -public class ModuleListSetting extends Setting> { +public class ModuleListSetting extends AbstractCollectionSetting> { private static List suggestions; public ModuleListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java index a0197e0f4f..0675c3eafd 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/PacketListSetting.java @@ -19,7 +19,7 @@ import java.util.function.Consumer; import java.util.function.Predicate; -public class PacketListSetting extends Setting>>> { +public class PacketListSetting extends AbstractCollectionSetting>>> { public final Predicate>> filter; private static List suggestions; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java index 6767344ede..bbfe2566ab 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ParticleTypeListSetting.java @@ -19,7 +19,7 @@ import java.util.List; import java.util.function.Consumer; -public class ParticleTypeListSetting extends Setting>> { +public class ParticleTypeListSetting extends AbstractCollectionSetting>> { public ParticleTypeListSetting(String name, String description, List> defaultValue, Consumer>> onChanged, Consumer>>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java index 1d597c604f..2d101e7f5b 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/ScreenHandlerListSetting.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.function.Consumer; -public class ScreenHandlerListSetting extends Setting>> { +public class ScreenHandlerListSetting extends AbstractCollectionSetting>> { public ScreenHandlerListSetting(String name, String description, List> defaultValue, Consumer>> onChanged, Consumer>>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/Setting.java b/src/main/java/meteordevelopment/meteorclient/settings/Setting.java index 443fe390fe..311e9adee0 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/Setting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/Setting.java @@ -5,10 +5,14 @@ package meteordevelopment.meteorclient.settings; +import com.mojang.brigadier.context.CommandContext; +import com.mojang.brigadier.suggestion.Suggestions; +import com.mojang.brigadier.suggestion.SuggestionsBuilder; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; import meteordevelopment.meteorclient.utils.misc.IGetter; import meteordevelopment.meteorclient.utils.misc.ISerializable; +import net.minecraft.command.CommandSource; import net.minecraft.nbt.NbtCompound; import net.minecraft.registry.Registry; import net.minecraft.util.Identifier; @@ -17,6 +21,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; public abstract class Setting implements IGetter, ISerializable { @@ -164,6 +169,14 @@ public static T parseId(Registry registry, String name) { return null; } + public CompletableFuture buildSuggestions(SuggestionsBuilder builder) { + Iterable identifiers = getIdentifierSuggestions(); + if (identifiers != null) { + return CommandSource.suggestIdentifiers(identifiers, builder); + } + return CommandSource.suggestMatching(getSuggestions(), builder); + } + @SuppressWarnings("unchecked") public abstract static class SettingBuilder { protected String name = "undefined", description = ""; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java index f516843a4c..0074c01a0c 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/SoundEventListSetting.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.function.Consumer; -public class SoundEventListSetting extends Setting> { +public class SoundEventListSetting extends AbstractCollectionSetting> { public SoundEventListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java index bfb06f5ea8..8448cb0bb7 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectAmplifierMapSetting.java @@ -15,7 +15,7 @@ import java.util.function.Consumer; -public class StatusEffectAmplifierMapSetting extends Setting> { +public class StatusEffectAmplifierMapSetting extends AbstractCollectionSetting> { public static final Reference2IntMap EMPTY_STATUS_EFFECT_MAP = createStatusEffectMap(); public StatusEffectAmplifierMapSetting(String name, String description, Reference2IntMap defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible) { diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java index e4335ca2d8..eed009f8f2 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StatusEffectListSetting.java @@ -18,7 +18,7 @@ import java.util.List; import java.util.function.Consumer; -public class StatusEffectListSetting extends Setting> { +public class StatusEffectListSetting extends AbstractCollectionSetting> { public StatusEffectListSetting(String name, String description, List defaultValue, Consumer> onChanged, Consumer>> onModuleActivated, IVisible visible) { super(name, description, defaultValue, onChanged, onModuleActivated, visible); } diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java index 8b35872aae..4d7796aab0 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StorageBlockListSetting.java @@ -27,7 +27,7 @@ import java.util.function.Consumer; import java.util.stream.Stream; -public class StorageBlockListSetting extends Setting>> { +public class StorageBlockListSetting extends AbstractCollectionSetting>> { public static final BlockEntityType[] STORAGE_BLOCKS = new BlockEntityType[]{ BlockEntityType.BARREL, BlockEntityType.BLAST_FURNACE, diff --git a/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java b/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java index d5f03502cb..dd9b1aa972 100644 --- a/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java +++ b/src/main/java/meteordevelopment/meteorclient/settings/StringListSetting.java @@ -22,7 +22,7 @@ import java.util.List; import java.util.function.Consumer; -public class StringListSetting extends Setting>{ +public class StringListSetting extends AbstractCollectionSetting>{ public final Class renderer; public final CharFilter filter; diff --git a/src/main/java/meteordevelopment/meteorclient/settings/groups/GroupSet.java b/src/main/java/meteordevelopment/meteorclient/settings/groups/GroupSet.java new file mode 100644 index 0000000000..33a5e93f3b --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/groups/GroupSet.java @@ -0,0 +1,238 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings.groups; + +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import meteordevelopment.meteorclient.MeteorClient; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +@Unmodifiable +public class GroupSet> implements Iterable, IGroup { + private Set cached; + private Set immediate; + private List include; + + private Predicate includeIf; + + public SetGroupEnumeration enumeration = null; + long version; + + private boolean isValid() { + if (cached == null) return false; + if (enumeration == null) return false; + return version == enumeration.getVersion(); + } + + public GroupSet() { + cached = null; + include = new ArrayList<>(); + immediate = new ReferenceOpenHashSet<>(); + } + + public GroupSet(@NotNull Collection d) { + cached = new ReferenceOpenHashSet<>(d); + include = new ArrayList<>(); + immediate = new ReferenceOpenHashSet<>(cached); + } + + public GroupSet(Collection d, @NotNull Collection g) { + cached = null; + include = new ArrayList<>(g); + immediate = d == null ? new ReferenceOpenHashSet<>() : new ReferenceOpenHashSet<>(d); + } + + @Override + public boolean add(T t) { + if (!immediate.contains(t)) { + immediate.add(t); + if (isValid()) cached.add(t); + return true; + } + return false; + } + + @Override + public boolean add(G g) { + if (!include.contains(g)) { + include.add(g); + cached = null; + return true; + } + return false; + } + + @Override + public boolean remove(T t) { + if (immediate.remove(t)) { + cached = null; + return true; + } + return false; + } + + @Override + public boolean remove(G g) { + if (include.remove(g)) { + cached = null; + return true; + } + return false; + } + + public void invalidate() { + cached = null; + } + + public void setIncludeCondition(Predicate includeIf) { + this.includeIf = includeIf; + cached = null; + } + + @Override + @Unmodifiable + public Set getAll() { + return getAllMatching(null); + } + + @Override + @Unmodifiable + public Set getAllMatching(@Nullable Predicate predicate) { + + if (isValid()) { + if (predicate == null) return cached; + return cached.stream().filter(predicate).collect(Collectors.toUnmodifiableSet()); + } + + if (enumeration != null) version = enumeration.getVersion(); + // debug statement + else if (cached != null && !cached.isEmpty()) MeteorClient.LOG.warn("Rebuild of temporary GroupSet"); + + Set set = new ReferenceOpenHashSet<>(immediate); + List> seen = new ArrayList<>(); + List> next = new ArrayList<>(); + + for (SetGroup g : include) { + g.internalGetAll(set, seen, next, predicate); + } + + if (includeIf != null) set.removeIf((t) -> !includeIf.test(t)); + + cached = set; + + return Collections.unmodifiableSet(cached); + } + + @Override + public boolean anyMatch(Predicate predicate) { + return false; + } + + public void set(GroupSet other) { + cached = null; + if (other.isValid()) { + cached = new ReferenceOpenHashSet<>(other.cached); + version = enumeration.getVersion(); + } + include = new ArrayList<>(other.include); + immediate = new ReferenceOpenHashSet<>(other.immediate); + } + + public void clear() { + if (cached != null) cached.clear(); + include.clear(); + immediate.clear(); + } + + @Override + @Unmodifiable + public Set getImmediate() { + return Collections.unmodifiableSet(immediate); + } + + @Override + @Unmodifiable + public List getGroups() { + return Collections.unmodifiableList(include); + } + + @Override + public boolean isEmpty() { + return getAll().isEmpty(); + } + + @Override + public boolean contains(Object o) { + return getAll().contains(o); + } + + @Override + public boolean containsAll(@NotNull Collection collection) { + getAll(); + for (T t : collection) if (!cached.contains(t)) return false; + return true; + } + + @Override + public boolean addAll(@NotNull Collection collection) { + boolean modified = false; + for (T t : collection) { + if (!immediate.contains(t)) { + immediate.add(t); + modified = true; + } + } + if (modified) cached = null; + return modified; + } + + @Override + public boolean addAllGroups(@NotNull Collection collection) { + boolean modified = false; + for (G g : collection) { + if (!include.contains(g)) { + include.add(g); + modified = true; + } + } + if (modified) cached = null; + return modified; + } + + @Override + public boolean removeAll(@NotNull Collection collection) { + cached = null; + return immediate.removeAll(collection); + } + + @Override + public boolean removeAllGroups(@NotNull Collection collection) { + cached = null; + return include.removeAll(collection); + } + + public int size() { + return getAll().size(); + } + + @Override + public @NotNull Iterator iterator() { + return getAll().iterator(); + } + + public @NotNull Object[] toArray() { + return getAll().toArray(); + } + + public @NotNull T1[] toArray(@NotNull T1[] t1s) { + return getAll().toArray(t1s); + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/groups/IGroup.java b/src/main/java/meteordevelopment/meteorclient/settings/groups/IGroup.java new file mode 100644 index 0000000000..51231ac6a9 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/groups/IGroup.java @@ -0,0 +1,59 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings.groups; + + +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + + +public interface IGroup> { + @Unmodifiable + Set getImmediate(); + + @Unmodifiable + Set getAll(); + @Unmodifiable + Set getAllMatching(Predicate predicate); + + boolean anyMatch(Predicate predicate); + + @Unmodifiable + List getGroups(); + + boolean add(T t); + boolean add(G g); + + boolean remove(G g); + boolean remove(T t); + + boolean addAll(@NotNull Collection collection); + + boolean addAllGroups(Collection collection); + boolean removeAll(@NotNull Collection collection); + boolean removeAllGroups(@NotNull Collection collection); + + default boolean containsAll(@NotNull Collection collection) { + return getAll().containsAll(collection); + } + + default boolean isEmpty() { + return getAll().isEmpty(); + } + + default boolean contains(Object o) { + return getAll().contains(o); + } + +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroup.java b/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroup.java new file mode 100644 index 0000000000..be29975336 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroup.java @@ -0,0 +1,168 @@ +/* + * This file is part of the Meteor Client distribution (https://github.com/MeteorDevelopment/meteor-client). + * Copyright (c) Meteor Development. + */ + +package meteordevelopment.meteorclient.settings.groups; + +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Unmodifiable; + +import javax.annotation.Nullable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.function.Predicate; + +public abstract class SetGroup> implements IGroup { + protected Set immediate = new ReferenceOpenHashSet<>(); + protected List include = new ArrayList<>(); + + final protected SetGroupEnumeration enumeration; + + public boolean isOf(SetGroupEnumeration of) { return enumeration == of; }; + + @Unmodifiable + public Set getImmediate() { + return immediate; + } + + public Set getAll() { + Set set = new ReferenceOpenHashSet<>(); + List> seen = new ArrayList<>(); + List> next = new ArrayList<>(); + internalGetAll(set, seen, next); + return set; + } + + public Set getAllMatching(Predicate predicate) { + Set set = new ReferenceOpenHashSet<>(); + List> seen = new ArrayList<>(); + List> next = new ArrayList<>(); + if (predicate == null) internalGetAll(set, seen, next); + else internalGetAll(set, seen, next, predicate); + return set; + } + + public void internalGetAll(Collection to, Collection> seen, List> next, Predicate predicate) { + next.clear(); + next.add(this); + for (int i = 0; i < next.size(); i++) { + SetGroup g = next.get(i); + if (seen.contains(g)) continue; + for (T t : g.immediate) { + if (predicate.test(t)) to.add(t); + } + next.addAll(g.include); + seen.add(g); + } + } + + public void internalGetAll(Collection to, Collection> seen, List> next) { + next.clear(); + next.add(this); + for (int i = 0; i < next.size(); i++) { + SetGroup g = next.get(i); + if (seen.contains(g)) continue; + to.addAll(g.immediate); + next.addAll(g.include); + seen.add(g); + } + } + + public boolean anyMatch(Predicate predicate) { + List> seen = new ArrayList<>(); + List> next = new ArrayList<>(); + next.add(this); + for (int i = 0; i < next.size(); i++) { + SetGroup g = next.get(i); + if (seen.contains(g)) continue; + if (g.immediate.stream().anyMatch(predicate)) return true; + next.addAll(g.include); + seen.add(g); + } + return false; + } + + @Unmodifiable + public List getGroups() { + return include; + } + + public boolean add(T t) { + if (!immediate.contains(t)) { + immediate.add(t); + enumeration.invalidate(); + return true; + } + return false; + } + + public boolean add(G g) { + if (!include.contains(g)) { + include.add(g); + enumeration.invalidate(); + return true; + } + return false; + } + + public boolean remove(G g) { + if (include.remove(g)) { + enumeration.invalidate(); + return true; + } + return false; + } + + public boolean remove(T t) { + if (immediate.remove(t)) { + enumeration.invalidate(); + return true; + } + return false; + } + + public boolean addAll(@NotNull Collection collection) { + boolean modified = false; + for (T t : collection) { + if (!immediate.contains(t)) { + immediate.add(t); + modified = true; + } + } + if (modified) enumeration.invalidate(); + return modified; + } + + public boolean addAllGroups(Collection collection) { + boolean modified = false; + for (G g : collection) { + if (!include.contains(g)) { + include.add(g); + modified = true; + } + } + if (modified) enumeration.invalidate();; + return modified; + } + + public boolean removeAll(@NotNull Collection collection) { + enumeration.invalidate(); + return immediate.removeAll(collection); + } + + public boolean removeAllGroups(@NotNull Collection collection) { + enumeration.invalidate(); + return include.removeAll(collection); + } + + public SetGroup(SetGroupEnumeration t) { enumeration = t; } + + @Override + public boolean equals(Object obj) { + return this == obj; + } +} diff --git a/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroupEnumeration.java b/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroupEnumeration.java new file mode 100644 index 0000000000..e3aab8b1b5 --- /dev/null +++ b/src/main/java/meteordevelopment/meteorclient/settings/groups/SetGroupEnumeration.java @@ -0,0 +1,11 @@ +package meteordevelopment.meteorclient.settings.groups; + +public class SetGroupEnumeration { + + long a = 0; + + public long getVersion() { return a; } + + public void invalidate() { a++; } + +} diff --git a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/HoleHud.java b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/HoleHud.java index da963f4230..448723c383 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/HoleHud.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/hud/elements/HoleHud.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.mixin.WorldRendererAccessor; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.hud.Hud; import meteordevelopment.meteorclient.systems.hud.HudElement; import meteordevelopment.meteorclient.systems.hud.HudElementInfo; @@ -18,8 +19,6 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.MathHelper; -import java.util.List; - import static meteordevelopment.meteorclient.MeteorClient.mc; public class HoleHud extends HudElement { @@ -31,7 +30,7 @@ public class HoleHud extends HudElement { // General - public final Setting> safe = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> safe = sgGeneral.add(new BlockListSetting.Builder() .name("safe-blocks") .description("Which blocks to consider safe.") .defaultValue(Blocks.OBSIDIAN, Blocks.BEDROCK, Blocks.CRYING_OBSIDIAN, Blocks.NETHERITE_BLOCK) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java index a7245f206e..4e1bade15d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoLog.java @@ -11,6 +11,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -31,8 +32,6 @@ import net.minecraft.util.Colors; import net.minecraft.util.Formatting; -import java.util.Set; - public class AutoLog extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgEntities = settings.createGroup("Entities"); @@ -98,7 +97,7 @@ public class AutoLog extends Module { // Entities - private final Setting>> entities = sgEntities.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgEntities.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Disconnects when a specified entity is present within a specified range.") .defaultValue(EntityType.END_CRYSTAL) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java index d22367c277..b1f934a501 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/AutoTrap.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -43,7 +44,7 @@ public class AutoTrap extends Module { // General - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("whitelist") .description("Which blocks to use.") .defaultValue(Blocks.OBSIDIAN, Blocks.CRYING_OBSIDIAN) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java index f978b420cd..bdd9ee3db6 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/BowAimbot.java @@ -8,6 +8,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -28,8 +29,6 @@ import net.minecraft.item.Items; import net.minecraft.util.math.Vec3d; -import java.util.Set; - public class BowAimbot extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -42,7 +41,7 @@ public class BowAimbot extends Module { .build() ); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Entities to attack.") .onlyAttackable() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java index b3e4461342..63a2557a3c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/CrystalAura.java @@ -19,6 +19,7 @@ import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -62,7 +63,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -148,7 +148,7 @@ public class CrystalAura extends Module { .build() ); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Entities to attack.") .onlyAttackable() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java index e93622a24c..7cb1ee4de2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Hitboxes.java @@ -6,6 +6,7 @@ package meteordevelopment.meteorclient.systems.modules.combat; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -16,13 +17,11 @@ import net.minecraft.item.MaceItem; import net.minecraft.registry.tag.ItemTags; -import java.util.Set; - public class Hitboxes extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgWeapon = settings.createGroup("Weapon Options"); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Which entities to target.") .defaultValue(EntityType.PLAYER) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java index 25ea0b41cf..b7698041c2 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/HoleFiller.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.mixin.DirectionAccessor; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -42,7 +43,7 @@ public class HoleFiller extends Module { private final SettingGroup sgSmart = settings.createGroup("Smart"); private final SettingGroup sgRender = settings.createGroup("Render"); - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Which blocks can be used to fill holes.") .defaultValue( diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java index 8726ebb3fc..6123d8c859 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/KillAura.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -46,7 +47,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; import java.util.function.Predicate; public class KillAura extends Module { @@ -116,7 +116,7 @@ public class KillAura extends Module { // Targeting - private final Setting>> entities = sgTargeting.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgTargeting.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Entities to attack.") .onlyAttackable() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfTrap.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfTrap.java index d1706de6b9..812d8091ce 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfTrap.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/SelfTrap.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.FindItemResult; @@ -43,7 +44,7 @@ public enum BottomMode { // General - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("whitelist") .description("Which blocks to use.") .defaultValue(Blocks.OBSIDIAN, Blocks.NETHERITE_BLOCK) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java index 6592396d5a..9aac17d990 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/combat/Surround.java @@ -12,6 +12,7 @@ import meteordevelopment.meteorclient.mixin.WorldRendererAccessor; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.DamageUtils; @@ -49,7 +50,7 @@ public class Surround extends Module { // General - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("What blocks to use for surround.") .defaultValue(Blocks.OBSIDIAN, Blocks.CRYING_OBSIDIAN, Blocks.NETHERITE_BLOCK) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/InventoryTweaks.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/InventoryTweaks.java index 8a13ebb7f2..1205fbbf1d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/InventoryTweaks.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/InventoryTweaks.java @@ -17,6 +17,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.HandledScreenAccessor; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -113,7 +114,7 @@ public class InventoryTweaks extends Module { // Anti drop - private final Setting> antiDropItems = sgAntiDrop.add(new ItemListSetting.Builder() + private final Setting.Group>> antiDropItems = sgAntiDrop.add(new ItemSetSetting.Builder() .name("anti-drop-items") .description("Items to prevent dropping. Doesn't work in creative inventory screen.") .build() @@ -134,7 +135,7 @@ public class InventoryTweaks extends Module { // Auto Drop - private final Setting> autoDropItems = sgAutoDrop.add(new ItemListSetting.Builder() + private final Setting.Group>> autoDropItems = sgAutoDrop.add(new ItemSetSetting.Builder() .name("auto-drop-items") .description("Items to drop.") .build() @@ -199,7 +200,7 @@ public class InventoryTweaks extends Module { .build() ); - private final Setting> dumpItems = sgStealDump.add(new ItemListSetting.Builder() + private final Setting.Group>> dumpItems = sgStealDump.add(new ItemSetSetting.Builder() .name("dump-items") .description("Items to dump.") .build() @@ -212,7 +213,7 @@ public class InventoryTweaks extends Module { .build() ); - private final Setting> stealItems = sgStealDump.add(new ItemListSetting.Builder() + private final Setting.Group>> stealItems = sgStealDump.add(new ItemSetSetting.Builder() .name("steal-items") .description("Items to steal.") .build() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java index aee4004eef..acfcf56431 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/misc/Notifier.java @@ -14,6 +14,7 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -112,7 +113,7 @@ public class Notifier extends Module { .build() ); - private final Setting>> entities = sgVisualRange.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgVisualRange.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Which entities to notify about.") .defaultValue(EntityType.PLAYER) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Scaffold.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Scaffold.java index ad02674d0f..fb317fe8fa 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Scaffold.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Scaffold.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.FindItemResult; @@ -34,7 +35,7 @@ public class Scaffold extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgRender = settings.createGroup("Render"); - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Selected blocks.") .build() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Slippy.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Slippy.java index 18ee10e8d7..ded90999d8 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Slippy.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/movement/Slippy.java @@ -6,12 +6,11 @@ package meteordevelopment.meteorclient.systems.modules.movement; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import net.minecraft.block.Block; -import java.util.List; - public class Slippy extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -31,14 +30,14 @@ public class Slippy extends Module { .build() ); - public final Setting> ignoredBlocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> ignoredBlocks = sgGeneral.add(new BlockListSetting.Builder() .name("ignored-blocks") .description("Decide which blocks not to slip on") .visible(() -> listMode.get() == ListMode.Blacklist) .build() ); - public final Setting> allowedBlocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> allowedBlocks = sgGeneral.add(new BlockListSetting.Builder() .name("allowed-blocks") .description("Decide which blocks to slip on") .visible(() -> listMode.get() == ListMode.Whitelist) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoEat.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoEat.java index 26dec3ad27..0ec6bb761a 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoEat.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoEat.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.pathing.PathManagers; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -39,7 +40,7 @@ public class AutoEat extends Module { private final SettingGroup sgThreshold = settings.createGroup("Threshold"); // General - public final Setting> blacklist = sgGeneral.add(new ItemListSetting.Builder() + public final Setting.Group>> blacklist = sgGeneral.add(new ItemSetSetting.Builder() .name("blacklist") .description("Which items to not eat.") .defaultValue( diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoMend.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoMend.java index 569400a272..e3161ab1bf 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoMend.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoMend.java @@ -6,10 +6,8 @@ package meteordevelopment.meteorclient.systems.modules.player; import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.ItemListSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -20,12 +18,10 @@ import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import java.util.List; - public class AutoMend extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting> blacklist = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> blacklist = sgGeneral.add(new ItemSetSetting.Builder() .name("blacklist") .description("Item blacklist.") .filter(item -> item.getComponents().get(DataComponentTypes.DAMAGE) != null) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoReplenish.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoReplenish.java index cdb30f7461..055dd973bc 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoReplenish.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoReplenish.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -19,7 +20,6 @@ import net.minecraft.item.Items; import java.util.Arrays; -import java.util.List; public class AutoReplenish extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -70,7 +70,7 @@ public class AutoReplenish extends Module { .build() ); - private final Setting> excludedItems = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> excludedItems = sgGeneral.add(new ItemSetSetting.Builder() .name("excluded-items") .description("Items that won't be replenished.") .build() @@ -131,7 +131,7 @@ private void checkSlot(int slot, ItemStack stack) { items[slot] = stack.copy(); if (slot == 9) slot = SlotUtils.OFFHAND; - + if (excludedItems.get().contains(stack.getItem())) return; if (excludedItems.get().contains(prevStack.getItem())) return; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java index fdc6774c86..98227ae4fe 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/AutoTool.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.entity.player.StartBreakingBlockEvent; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -28,7 +29,6 @@ import net.minecraft.registry.tag.BlockTags; import net.minecraft.registry.tag.ItemTags; -import java.util.List; import java.util.function.Predicate; public class AutoTool extends Module { @@ -98,7 +98,7 @@ public class AutoTool extends Module { .build() ); - private final Setting> whitelist = sgWhitelist.add(new ItemListSetting.Builder() + private final Setting.Group>> whitelist = sgWhitelist.add(new ItemSetSetting.Builder() .name("whitelist") .description("The tools you want to use.") .visible(() -> listMode.get() == ListMode.Whitelist) @@ -106,7 +106,7 @@ public class AutoTool extends Module { .build() ); - private final Setting> blacklist = sgWhitelist.add(new ItemListSetting.Builder() + private final Setting.Group>> blacklist = sgWhitelist.add(new ItemSetSetting.Builder() .name("blacklist") .description("The tools you don't want to use.") .visible(() -> listMode.get() == ListMode.Blacklist) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/FastUse.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/FastUse.java index 0a17c7d48a..df451e0a58 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/FastUse.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/FastUse.java @@ -6,14 +6,13 @@ package meteordevelopment.meteorclient.systems.modules.player; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import net.minecraft.item.BlockItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import java.util.List; - public class FastUse extends Module { public enum Mode { All, @@ -29,7 +28,7 @@ public enum Mode { .build() ); - private final Setting> items = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> items = sgGeneral.add(new ItemSetSetting.Builder() .name("items") .description("Which items should fast place work on in \"Some\" mode.") .visible(() -> mode.get() == Mode.Some) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java index 4bea37d511..ab3d8ad2ec 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoInteract.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.events.entity.player.InteractEntityEvent; import meteordevelopment.meteorclient.events.entity.player.StartBreakingBlockEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; @@ -24,16 +25,13 @@ import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.math.BlockPos; -import java.util.List; -import java.util.Set; - public class NoInteract extends Module { private final SettingGroup sgBlocks = settings.createGroup("Blocks"); private final SettingGroup sgEntities = settings.createGroup("Entities"); // Blocks - private final Setting> blockMine = sgBlocks.add(new BlockListSetting.Builder() + private final Setting.Group>> blockMine = sgBlocks.add(new BlockListSetting.Builder() .name("block-mine") .description("Cancels block mining.") .build() @@ -46,7 +44,7 @@ public class NoInteract extends Module { .build() ); - private final Setting> blockInteract = sgBlocks.add(new BlockListSetting.Builder() + private final Setting.Group>> blockInteract = sgBlocks.add(new BlockListSetting.Builder() .name("block-interact") .description("Cancels block interaction.") .build() @@ -68,7 +66,7 @@ public class NoInteract extends Module { // Entities - private final Setting>> entityHit = sgEntities.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entityHit = sgEntities.add(new EntityTypeSetSetting.Builder() .name("entity-hit") .description("Cancel entity hitting.") .onlyAttackable() @@ -82,7 +80,7 @@ public class NoInteract extends Module { .build() ); - private final Setting>> entityInteract = sgEntities.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entityInteract = sgEntities.add(new EntityTypeSetSetting.Builder() .name("entity-interact") .description("Cancel entity interaction.") .onlyAttackable() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoMiningTrace.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoMiningTrace.java index 2d8858b463..0bff72f605 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoMiningTrace.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/NoMiningTrace.java @@ -5,22 +5,18 @@ package meteordevelopment.meteorclient.systems.modules.player; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.EntityTypeListSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; import net.minecraft.registry.tag.ItemTags; -import java.util.Set; - public class NoMiningTrace extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("blacklisted-entities") .description("Entities you will interact with as normal.") .defaultValue() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java index 1f5f738693..6c8a4fde59 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/player/SpeedMine.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.mixin.ClientPlayerInteractionManagerAccessor; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -18,8 +19,6 @@ import net.minecraft.network.packet.c2s.play.PlayerActionC2SPacket; import net.minecraft.util.math.BlockPos; -import java.util.List; - import static net.minecraft.entity.effect.StatusEffects.HASTE; public class SpeedMine extends Module { @@ -32,7 +31,7 @@ public class SpeedMine extends Module { .build() ); - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Selected blocks.") .filter(block -> block.getHardness() > 0) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Chams.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Chams.java index c6280df9cc..61bc45fed0 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Chams.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Chams.java @@ -8,6 +8,7 @@ import meteordevelopment.meteorclient.MeteorClient; import meteordevelopment.meteorclient.renderer.MeteorRenderPipelines; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.render.color.SettingColor; @@ -16,8 +17,6 @@ import net.minecraft.entity.EntityType; import net.minecraft.util.Identifier; -import java.util.Set; - public class Chams extends Module { private final SettingGroup sgThroughWalls = settings.createGroup("Through Walls"); private final SettingGroup sgPlayers = settings.createGroup("Players"); @@ -26,7 +25,7 @@ public class Chams extends Module { // Through walls - public final Setting>> entities = sgThroughWalls.add(new EntityTypeListSetting.Builder() + public final Setting, GroupedSetSetting.Groups>.Group>> entities = sgThroughWalls.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Select entities to show through walls.") .onlyAttackable() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java index 284eef7afe..867f16b71c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ESP.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; @@ -29,8 +30,6 @@ import net.minecraft.util.math.MathHelper; import org.joml.Vector3d; -import java.util.Set; - public class ESP extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); private final SettingGroup sgColors = settings.createGroup("Colors"); @@ -114,7 +113,7 @@ public class ESP extends Module { .build() ); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Select specific entities.") .defaultValue(EntityType.PLAYER) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ItemHighlight.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ItemHighlight.java index 3b4d786bb1..6c929c10fa 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ItemHighlight.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/ItemHighlight.java @@ -5,22 +5,18 @@ package meteordevelopment.meteorclient.systems.modules.render; -import meteordevelopment.meteorclient.settings.ColorSetting; -import meteordevelopment.meteorclient.settings.ItemListSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.render.color.SettingColor; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import java.util.List; - public class ItemHighlight extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting> items = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> items = sgGeneral.add(new ItemSetSetting.Builder() .name("items") .description("Items to highlight.") .build() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java index ccf56bef3a..5196c21fd9 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Nametags.java @@ -13,6 +13,7 @@ import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; @@ -55,7 +56,7 @@ public class Nametags extends Module { // General - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Select entities to draw nametags on.") .defaultValue(EntityType.PLAYER, EntityType.ITEM) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/NoRender.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/NoRender.java index 145a1ee45a..a7f7cb53e4 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/NoRender.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/NoRender.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.world.ChunkOcclusionEvent; import meteordevelopment.meteorclient.events.world.ParticleEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.orbit.EventHandler; @@ -21,7 +22,6 @@ import net.minecraft.particle.ParticleTypes; import java.util.List; -import java.util.Set; public class NoRender extends Module { private final SettingGroup sgOverlay = settings.createGroup("Overlay"); @@ -315,7 +315,7 @@ public class NoRender extends Module { .build() ); - private final Setting> blockEntities = sgWorld.add(new BlockListSetting.Builder() + private final Setting.Group>> blockEntities = sgWorld.add(new BlockListSetting.Builder() .name("block-entities") .description("Block entities (chest, shulker block, etc.) to not render.") .filter(block -> block instanceof BlockEntityProvider && !(block instanceof AbstractBannerBlock)) @@ -324,7 +324,7 @@ public class NoRender extends Module { // Entity - private final Setting>> entities = sgEntity.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgEntity.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Disables rendering of selected entities.") .build() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java index edac39cb37..5ae1fd9f04 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Tracers.java @@ -9,6 +9,7 @@ import meteordevelopment.meteorclient.events.render.Render3DEvent; import meteordevelopment.meteorclient.renderer.Renderer2D; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.config.Config; import meteordevelopment.meteorclient.systems.friends.Friends; import meteordevelopment.meteorclient.systems.modules.Categories; @@ -31,7 +32,6 @@ import java.time.Duration; import java.time.Instant; -import java.util.Set; public class Tracers extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -45,7 +45,7 @@ public enum TracerStyle { // General - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Select specific entities.") .defaultValue(EntityType.PLAYER) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Trajectories.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Trajectories.java index 34f769ddfb..382ff8719b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Trajectories.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Trajectories.java @@ -8,6 +8,7 @@ import meteordevelopment.meteorclient.events.render.Render3DEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -39,7 +40,7 @@ public class Trajectories extends Module { // General - private final Setting> items = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> items = sgGeneral.add(new ItemSetSetting.Builder() .name("items") .description("Items to display trajectories for.") .defaultValue(getDefaultItems()) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java index be042352c5..e75b9ecbaf 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/WallHack.java @@ -10,14 +10,13 @@ import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.widgets.WWidget; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.orbit.EventHandler; import net.irisshaders.iris.api.v0.IrisApi; import net.minecraft.block.Block; -import java.util.List; - public class WallHack extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -35,10 +34,9 @@ public class WallHack extends Module { .build() ); - public final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("What blocks should be targeted for Wall Hack.") - .defaultValue() .onChanged(onChanged -> { if (isActive()) mc.worldRenderer.reload(); }) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java index 351a230172..8aedd12824 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/Xray.java @@ -12,6 +12,7 @@ import meteordevelopment.meteorclient.gui.GuiTheme; import meteordevelopment.meteorclient.gui.widgets.WWidget; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -33,7 +34,7 @@ public class Xray extends Module { public static final List ORES = List.of(Blocks.COAL_ORE, Blocks.DEEPSLATE_COAL_ORE, Blocks.IRON_ORE, Blocks.DEEPSLATE_IRON_ORE, Blocks.GOLD_ORE, Blocks.DEEPSLATE_GOLD_ORE, Blocks.LAPIS_ORE, Blocks.DEEPSLATE_LAPIS_ORE, Blocks.REDSTONE_ORE, Blocks.DEEPSLATE_REDSTONE_ORE, Blocks.DIAMOND_ORE, Blocks.DEEPSLATE_DIAMOND_ORE, Blocks.EMERALD_ORE, Blocks.DEEPSLATE_EMERALD_ORE, Blocks.COPPER_ORE, Blocks.DEEPSLATE_COPPER_ORE, Blocks.NETHER_GOLD_ORE, Blocks.NETHER_QUARTZ_ORE, Blocks.ANCIENT_DEBRIS); - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("whitelist") .description("Which blocks to show x-rayed.") .defaultValue(ORES) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/BlockESP.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/BlockESP.java index 8cfe86c072..657d6d0fb9 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/BlockESP.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/BlockESP.java @@ -14,6 +14,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -27,7 +28,6 @@ import net.minecraft.world.dimension.DimensionType; import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.ExecutorService; @@ -38,7 +38,7 @@ public class BlockESP extends Module { // General - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Blocks to search for.") .onChanged(blocks1 -> { @@ -161,7 +161,7 @@ private void onChunkData(ChunkDataEvent event) { private void searchChunk(Chunk chunk) { workerThread.submit(() -> { if (!isActive()) return; - ESPChunk schunk = ESPChunk.searchChunk(chunk, blocks.get()); + ESPChunk schunk = ESPChunk.searchChunk(chunk, blocks.get().getAll()); if (schunk.size() > 0) { synchronized (chunks) { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/ESPChunk.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/ESPChunk.java index 0fac693cf3..f116134dc7 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/ESPChunk.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/render/blockesp/ESPChunk.java @@ -15,7 +15,7 @@ import net.minecraft.world.Heightmap; import net.minecraft.world.chunk.Chunk; -import java.util.List; +import java.util.Collection; import static meteordevelopment.meteorclient.MeteorClient.mc; import static meteordevelopment.meteorclient.utils.Utils.getRenderDistance; @@ -86,7 +86,7 @@ public void render(Render3DEvent event) { } - public static ESPChunk searchChunk(Chunk chunk, List blocks) { + public static ESPChunk searchChunk(Chunk chunk, Collection blocks) { ESPChunk schunk = new ESPChunk(chunk.getPos().x, chunk.getPos().z); if (schunk.shouldBeDeleted()) return schunk; diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java index 98c647ecd5..cf4d00908c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoBreed.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.player.PlayerUtils; @@ -20,12 +21,11 @@ import java.util.ArrayList; import java.util.List; -import java.util.Set; public class AutoBreed extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Entities to breed.") .defaultValue(EntityType.HORSE, EntityType.DONKEY, EntityType.COW, diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java index cad9a7ed35..181d042013 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoMount.java @@ -8,10 +8,8 @@ //Created by squidoodly 16/07/2020 import meteordevelopment.meteorclient.events.world.TickEvent; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.EntityTypeListSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.EntityUtils; @@ -30,8 +28,6 @@ import net.minecraft.util.Hand; import net.minecraft.util.hit.EntityHitResult; -import java.util.Set; - public class AutoMount extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -49,7 +45,7 @@ public class AutoMount extends Module { .build() ); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Rideable entities.") .filter(EntityUtils::isRideable) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java index 5c93427b05..8340b2090c 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoNametag.java @@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.entity.SortPriority; @@ -25,12 +26,11 @@ import net.minecraft.util.hit.EntityHitResult; import java.util.Iterator; -import java.util.Set; public class AutoNametag extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Which entities to nametag.") .build() diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoSmelter.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoSmelter.java index 80c600eeeb..509869339d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoSmelter.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/AutoSmelter.java @@ -6,10 +6,8 @@ package meteordevelopment.meteorclient.systems.modules.world; import meteordevelopment.meteorclient.mixininterface.IAbstractFurnaceScreenHandler; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.ItemListSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -20,26 +18,24 @@ import net.minecraft.recipe.RecipePropertySet; import net.minecraft.screen.AbstractFurnaceScreenHandler; -import java.util.List; - public class AutoSmelter extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - private final Setting> fuelItems = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> fuelItems = sgGeneral.add(new ItemSetSetting.Builder() .name("fuel-items") .description("Items to use as fuel") .defaultValue(Items.COAL, Items.CHARCOAL) .filter(this::fuelItemFilter) - .bypassFilterWhenSavingAndLoading() + //.bypassFilterWhenSavingAndLoading() .build() ); - private final Setting> smeltableItems = sgGeneral.add(new ItemListSetting.Builder() + private final Setting.Group>> smeltableItems = sgGeneral.add(new ItemSetSetting.Builder() .name("smeltable-items") .description("Items to smelt") .defaultValue(Items.IRON_ORE, Items.GOLD_ORE, Items.COPPER_ORE, Items.RAW_IRON, Items.RAW_COPPER, Items.RAW_GOLD) .filter(this::smeltableItemFilter) - .bypassFilterWhenSavingAndLoading() + //.bypassFilterWhenSavingAndLoading() .build() ); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Collisions.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Collisions.java index ab424c1a0d..8e547686e4 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Collisions.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Collisions.java @@ -9,10 +9,8 @@ import meteordevelopment.meteorclient.events.packets.PacketEvent; import meteordevelopment.meteorclient.events.world.CollisionShapeEvent; import meteordevelopment.meteorclient.mixininterface.IVec3d; -import meteordevelopment.meteorclient.settings.BlockListSetting; -import meteordevelopment.meteorclient.settings.BoolSetting; -import meteordevelopment.meteorclient.settings.Setting; -import meteordevelopment.meteorclient.settings.SettingGroup; +import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.orbit.EventHandler; @@ -21,12 +19,10 @@ import net.minecraft.network.packet.c2s.play.VehicleMoveC2SPacket; import net.minecraft.util.shape.VoxelShapes; -import java.util.List; - public class Collisions extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); - public final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("What blocks should be added collision box.") .filter(this::blockFilter) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Flamethrower.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Flamethrower.java index 4b4c2719a3..adcf5578a3 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Flamethrower.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Flamethrower.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.HorizontalDirection; @@ -26,8 +27,6 @@ import net.minecraft.util.math.Direction; import net.minecraft.util.math.Vec3d; -import java.util.Set; - public class Flamethrower extends Module { private final SettingGroup sgGeneral = settings.getDefaultGroup(); @@ -73,7 +72,7 @@ public class Flamethrower extends Module { .build() ); - private final Setting>> entities = sgGeneral.add(new EntityTypeListSetting.Builder() + private final Setting, GroupedSetSetting.Groups>.Group>> entities = sgGeneral.add(new EntityTypeSetSetting.Builder() .name("entities") .description("Entities to cook.") .defaultValue( diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java index 9a82372443..de60792752 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/HighwayBuilder.java @@ -15,6 +15,7 @@ import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.renderer.text.TextRenderer; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.systems.modules.Modules; @@ -71,7 +72,6 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Iterator; -import java.util.List; import java.util.function.Predicate; @SuppressWarnings("ConstantConditions") @@ -254,7 +254,7 @@ public enum BlockadeType { // Paving - public final Setting> blocksToPlace = sgPaving.add(new BlockListSetting.Builder() + public final Setting.Group>> blocksToPlace = sgPaving.add(new BlockListSetting.Builder() .name("blocks-to-place") .description("Blocks it is allowed to place.") .defaultValue(Blocks.OBSIDIAN) @@ -288,7 +288,7 @@ public enum BlockadeType { // Inventory - private final Setting> trashItems = sgInventory.add(new ItemListSetting.Builder() + private final Setting.Group>> trashItems = sgInventory.add(new ItemSetSetting.Builder() .name("trash-items") .description("Items that are considered trash and can be thrown out.") .defaultValue( diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/InfinityMiner.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/InfinityMiner.java index 18c85701c6..d59a1c5827 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/InfinityMiner.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/InfinityMiner.java @@ -13,6 +13,7 @@ import baritone.api.process.IMineProcess; import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -31,7 +32,6 @@ import net.minecraft.text.Text; import net.minecraft.util.math.BlockPos; -import java.util.List; import java.util.function.Predicate; public class InfinityMiner extends Module { @@ -40,7 +40,7 @@ public class InfinityMiner extends Module { // General - public final Setting> targetBlocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> targetBlocks = sgGeneral.add(new BlockListSetting.Builder() .name("target-blocks") .description("The target blocks to mine.") .defaultValue(Blocks.DIAMOND_ORE, Blocks.DEEPSLATE_DIAMOND_ORE) @@ -48,14 +48,14 @@ public class InfinityMiner extends Module { .build() ); - public final Setting> targetItems = sgGeneral.add(new ItemListSetting.Builder() + public final Setting.Group>> targetItems = sgGeneral.add(new ItemSetSetting.Builder() .name("target-items") .description("The target items to collect.") .defaultValue(Items.DIAMOND) .build() ); - public final Setting> repairBlocks = sgGeneral.add(new BlockListSetting.Builder() + public final Setting.Group>> repairBlocks = sgGeneral.add(new BlockListSetting.Builder() .name("repair-blocks") .description("The repair blocks to mine.") .defaultValue(Blocks.COAL_ORE, Blocks.REDSTONE_ORE, Blocks.NETHER_QUARTZ_ORE) @@ -204,14 +204,14 @@ private void mineTargetBlocks() { Block[] array = new Block[targetBlocks.get().size()]; baritone.getPathingBehavior().cancelEverything(); - baritone.getMineProcess().mine(targetBlocks.get().toArray(array)); + baritone.getMineProcess().mine(targetBlocks.get().getAll().toArray(array)); } private void mineRepairBlocks() { Block[] array = new Block[repairBlocks.get().size()]; baritone.getPathingBehavior().cancelEverything(); - baritone.getMineProcess().mine(repairBlocks.get().toArray(array)); + baritone.getMineProcess().mine(repairBlocks.get().getAll().toArray(array)); } private void logOut() { diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/LiquidFiller.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/LiquidFiller.java index cd3b248e9e..44df7ae9fb 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/LiquidFiller.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/LiquidFiller.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -105,23 +106,16 @@ public class LiquidFiller extends Module { .build() ); - private final Setting> whitelist = sgWhitelist.add(new BlockListSetting.Builder() + private final Setting.Group>> whitelist = sgWhitelist.add(new BlockListSetting.Builder() .name("whitelist") .description("The allowed blocks that it will use to fill up the liquid.") - .defaultValue( - Blocks.DIRT, - Blocks.COBBLESTONE, - Blocks.STONE, - Blocks.NETHERRACK, - Blocks.DIORITE, - Blocks.GRANITE, - Blocks.ANDESITE - ) + .defaultValue(Blocks.COBBLESTONE, Blocks.COBBLED_DEEPSLATE) + .defaultGroups(BlockListSetting.TERRAIN) .visible(() -> listMode.get() == ListMode.Whitelist) .build() ); - private final Setting> blacklist = sgWhitelist.add(new BlockListSetting.Builder() + private final Setting.Group>> blacklist = sgWhitelist.add(new BlockListSetting.Builder() .name("blacklist") .description("The denied blocks that it not will use to fill up the liquid.") .visible(() -> listMode.get() == ListMode.Blacklist) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java index a644676956..40a14e5c3d 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/Nuker.java @@ -13,6 +13,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -196,14 +197,14 @@ public class Nuker extends Module { .build() ); - private final Setting> blacklist = sgWhitelist.add(new BlockListSetting.Builder() + private final Setting.Group>> blacklist = sgWhitelist.add(new BlockListSetting.Builder() .name("blacklist") .description("The blocks you don't want to mine.") .visible(() -> listMode.get() == ListMode.Blacklist) .build() ); - private final Setting> whitelist = sgWhitelist.add(new BlockListSetting.Builder() + private final Setting.Group>> whitelist = sgWhitelist.add(new BlockListSetting.Builder() .name("whitelist") .description("The blocks you want to mine.") .visible(() -> listMode.get() == ListMode.Whitelist) @@ -532,12 +533,16 @@ private void addTargetedBlockToList() { BlockPos pos = ((BlockHitResult) hitResult).getBlockPos(); Block targetBlock = mc.world.getBlockState(pos).getBlock(); - List list = listMode.get() == ListMode.Whitelist ? whitelist.get() : blacklist.get(); + GroupSet.Group> list = listMode.get() == ListMode.Whitelist ? whitelist.get() : blacklist.get(); String modeName = listMode.get().name(); if (list.contains(targetBlock)) { list.remove(targetBlock); - info("Removed " + Names.get(targetBlock) + " from " + modeName); + if (list.contains(targetBlock)) { + info("Removed " + Names.get(targetBlock) + " from " + modeName + ", but it is also included by a group"); + } else { + info("Removed " + Names.get(targetBlock) + " from " + modeName); + } } else { list.add(targetBlock); info("Added " + Names.get(targetBlock) + " to " + modeName); diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/SpawnProofer.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/SpawnProofer.java index b1c7856378..4e57b2641b 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/SpawnProofer.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/SpawnProofer.java @@ -7,6 +7,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.misc.Pool; @@ -72,7 +73,7 @@ public class SpawnProofer extends Module { .build() ); - private final Setting> blocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> blocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Block to use for spawn proofing.") .defaultValue(Blocks.TORCH, Blocks.STONE_BUTTON, Blocks.STONE_SLAB) diff --git a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java index 1060dd4082..34fd9328c6 100644 --- a/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java +++ b/src/main/java/meteordevelopment/meteorclient/systems/modules/world/VeinMiner.java @@ -10,6 +10,7 @@ import meteordevelopment.meteorclient.events.world.TickEvent; import meteordevelopment.meteorclient.renderer.ShapeMode; import meteordevelopment.meteorclient.settings.*; +import meteordevelopment.meteorclient.settings.groups.GroupSet; import meteordevelopment.meteorclient.systems.modules.Categories; import meteordevelopment.meteorclient.systems.modules.Module; import meteordevelopment.meteorclient.utils.Utils; @@ -20,7 +21,6 @@ import meteordevelopment.orbit.EventHandler; import net.minecraft.block.Block; import net.minecraft.block.BlockState; -import net.minecraft.block.Blocks; import net.minecraft.item.Item; import net.minecraft.util.Hand; import net.minecraft.util.math.BlockPos; @@ -52,10 +52,10 @@ public class VeinMiner extends Module { // General - private final Setting> selectedBlocks = sgGeneral.add(new BlockListSetting.Builder() + private final Setting.Group>> selectedBlocks = sgGeneral.add(new BlockListSetting.Builder() .name("blocks") .description("Which blocks to select.") - .defaultValue(Blocks.STONE, Blocks.DIRT, Blocks.GRASS_BLOCK) + .defaultGroups(BlockListSetting.TERRAIN) .build() ); diff --git a/src/main/resources/assets/meteor-client/textures/icons/gui/arrowhead.png b/src/main/resources/assets/meteor-client/textures/icons/gui/arrowhead.png new file mode 100644 index 0000000000..75f095f291 Binary files /dev/null and b/src/main/resources/assets/meteor-client/textures/icons/gui/arrowhead.png differ diff --git a/src/main/resources/assets/meteor-client/textures/icons/gui/double-arrowhead.png b/src/main/resources/assets/meteor-client/textures/icons/gui/double-arrowhead.png new file mode 100644 index 0000000000..ec15768a20 Binary files /dev/null and b/src/main/resources/assets/meteor-client/textures/icons/gui/double-arrowhead.png differ