From c18bfb0db870607b7899435341b2fa0fe947b7fa Mon Sep 17 00:00:00 2001 From: Aaron <51387595+AzureAaron@users.noreply.github.com> Date: Thu, 9 Jan 2025 11:08:14 -0500 Subject: [PATCH] Carnival Helpers (#1124) * Carnival Helpers * changes --- .../config/categories/HelperCategory.java | 21 +++++ .../config/configs/HelperConfig.java | 11 +++ .../skyblock/carnival/CatchAFish.java | 41 +++++++++ .../skyblock/carnival/ChivalrousCarnival.java | 12 +++ .../skyblock/carnival/ZombieShootout.java | 85 +++++++++++++++++++ .../skyblocker/skyblock/entity/MobGlow.java | 6 ++ .../java/de/hysky/skyblocker/utils/Area.java | 24 ++++++ .../java/de/hysky/skyblocker/utils/Utils.java | 27 ++++++ .../assets/skyblocker/lang/en_us.json | 6 ++ 9 files changed, 233 insertions(+) create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/carnival/CatchAFish.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/carnival/ChivalrousCarnival.java create mode 100644 src/main/java/de/hysky/skyblocker/skyblock/carnival/ZombieShootout.java create mode 100644 src/main/java/de/hysky/skyblocker/utils/Area.java diff --git a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java index 94f0fc0c27..31bac29327 100644 --- a/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java +++ b/src/main/java/de/hysky/skyblocker/config/categories/HelperCategory.java @@ -227,6 +227,27 @@ public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig .build()) .build()) + .group(OptionGroup.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.carnival")) + .collapsed(true) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.carnival.catchAFishHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.carnival.catchAFishHelper.@Tooltip"))) + .binding(defaults.helpers.carnival.catchAFishHelper, + () -> config.helpers.carnival.catchAFishHelper, + newValue -> config.helpers.carnival.catchAFishHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .option(Option.createBuilder() + .name(Text.translatable("skyblocker.config.helpers.carnival.zombieShootoutHelper")) + .description(OptionDescription.of(Text.translatable("skyblocker.config.helpers.carnival.zombieShootoutHelper.@Tooltip"))) + .binding(defaults.helpers.carnival.zombieShootoutHelper, + () -> config.helpers.carnival.zombieShootoutHelper, + newValue -> config.helpers.carnival.zombieShootoutHelper = newValue) + .controller(ConfigUtils::createBooleanController) + .build()) + .build()) + //Bazaar .group(OptionGroup.createBuilder() .name(Text.translatable("skyblocker.config.helpers.bazaar")) diff --git a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java index 2b1944aea4..6541dee9be 100644 --- a/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java +++ b/src/main/java/de/hysky/skyblocker/config/configs/HelperConfig.java @@ -32,6 +32,9 @@ public class HelperConfig { @SerialEntry public ChocolateFactory chocolateFactory = new ChocolateFactory(); + @SerialEntry + public Carnival carnival = new Carnival(); + @SerialEntry public Bazaar bazaar = new Bazaar(); @@ -107,6 +110,14 @@ public static class ChocolateFactory { public boolean straySound = true; } + public static class Carnival { + @SerialEntry + public boolean catchAFishHelper = true; + + @SerialEntry + public boolean zombieShootoutHelper = true; + } + public static class Bazaar { @SerialEntry public boolean enableBazaarHelper = true; diff --git a/src/main/java/de/hysky/skyblocker/skyblock/carnival/CatchAFish.java b/src/main/java/de/hysky/skyblocker/skyblock/carnival/CatchAFish.java new file mode 100644 index 0000000000..a9df6c3df3 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/carnival/CatchAFish.java @@ -0,0 +1,41 @@ +package de.hysky.skyblocker.skyblock.carnival; + +import java.awt.Color; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.entity.MobGlow; +import de.hysky.skyblocker.utils.ItemUtils; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.decoration.ArmorStandEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; + +public class CatchAFish { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + private static final Box AREA = Box.enclosing(new BlockPos(-69, 65, -5), new BlockPos(-87, 84, 22)); + private static final String YELLOW_FISH_TEXTURE = "ewogICJ0aW1lc3RhbXAiIDogMTcyMDA1MjU4MjAwMSwKICAicHJvZmlsZUlkIiA6ICIzM2Y4ZGExMTU1MzQ0YWQ5OWQ0Y2Q2ZjNhYjFjMjNhYSIsCiAgInByb2ZpbGVOYW1lIiA6ICJCXzFfUl9CIiwKICAic2lnbmF0dXJlUmVxdWlyZWQiIDogdHJ1ZSwKICAidGV4dHVyZXMiIDogewogICAgIlNLSU4iIDogewogICAgICAidXJsIiA6ICJodHRwOi8vdGV4dHVyZXMubWluZWNyYWZ0Lm5ldC90ZXh0dXJlLzM2MGY0Zjk5Yzc4YWRkZGVhYjI3NmViZGY2YWI5YTBmY2ZmYWJkNDlmMGI1NDNlMTk4MWFjN2JkM2Q1NWIxOGEiLAogICAgICAibWV0YWRhdGEiIDogewogICAgICAgICJtb2RlbCIgOiAic2xpbSIKICAgICAgfQogICAgfQogIH0KfQ=="; + private static final int YELLOW = Color.YELLOW.getRGB(); + + public static int getFishGlowColor(ArmorStandEntity armorStand) { + ItemStack stack = armorStand.getEquippedStack(EquipmentSlot.HEAD); + + if (!stack.isEmpty() && stack.isOf(Items.PLAYER_HEAD) && ItemUtils.getHeadTexture(stack).equals(YELLOW_FISH_TEXTURE)) { + return YELLOW; + } + + return MobGlow.NO_GLOW; + } + + public static boolean isInCatchAFish() { + if (ChivalrousCarnival.isInCarnival() && SkyblockerConfigManager.get().helpers.carnival.catchAFishHelper && CLIENT.player != null) { + BlockPos pos = CLIENT.player.getBlockPos(); + + return AREA.contains(pos.getX(), pos.getY(), pos.getZ()); + } + + return false; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/carnival/ChivalrousCarnival.java b/src/main/java/de/hysky/skyblocker/skyblock/carnival/ChivalrousCarnival.java new file mode 100644 index 0000000000..5f38ed9423 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/carnival/ChivalrousCarnival.java @@ -0,0 +1,12 @@ +package de.hysky.skyblocker.skyblock.carnival; + +import de.hysky.skyblocker.utils.Area; +import de.hysky.skyblocker.utils.Location; +import de.hysky.skyblocker.utils.Utils; + +public class ChivalrousCarnival { + + protected static boolean isInCarnival() { + return Utils.isOnSkyblock() && Utils.getLocation() == Location.HUB && Utils.getArea() == Area.CARNIVAL; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/carnival/ZombieShootout.java b/src/main/java/de/hysky/skyblocker/skyblock/carnival/ZombieShootout.java new file mode 100644 index 0000000000..bd04730079 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/carnival/ZombieShootout.java @@ -0,0 +1,85 @@ +package de.hysky.skyblocker.skyblock.carnival; + +import de.hysky.skyblocker.annotations.Init; +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.skyblock.entity.MobGlow; +import de.hysky.skyblocker.utils.render.RenderHelper; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext; +import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.client.MinecraftClient; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.mob.ZombieEntity; +import net.minecraft.item.Item; +import net.minecraft.item.Items; +import net.minecraft.state.property.Properties; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Box; + +public class ZombieShootout { + private static final MinecraftClient CLIENT = MinecraftClient.getInstance(); + private static final float[] RED = { 1, 0, 0 }; + private static final Box SHOOTING_BOX = Box.enclosing(new BlockPos(-100, 70, 15), new BlockPos(-102, 75, 13)); + private static final BlockPos[] LAMPS = { + new BlockPos(-96, 76, 31), + new BlockPos(-99, 77, 32), + new BlockPos(-102, 75, 32), + new BlockPos(-106, 77, 31), + new BlockPos(-109, 75, 30), + new BlockPos(-112, 76, 28), + new BlockPos(-115, 77, 25), + new BlockPos(-117, 76, 22), + new BlockPos(-118, 76, 19), + new BlockPos(-119, 75, 15), + new BlockPos(-119, 77, 12), + new BlockPos(-118, 76, 9) + }; + + @Init + public static void init() { + WorldRenderEvents.AFTER_TRANSLUCENT.register(ZombieShootout::render); + } + + private static void render(WorldRenderContext context) { + if (isInZombieShootout() && CLIENT.world != null) { + for (BlockPos pos : LAMPS) { + BlockState state = CLIENT.world.getBlockState(pos); + Block block = state.getBlock(); + + if (block.equals(Blocks.REDSTONE_LAMP) && state.contains(Properties.LIT) && state.get(Properties.LIT)) { + RenderHelper.renderOutline(context, pos, RED, 5f, false); + } + } + } + } + + public static int getZombieGlowColor(ZombieEntity zombie) { + if (!zombie.getEquippedStack(EquipmentSlot.CHEST).isEmpty()) { + Item item = zombie.getEquippedStack(EquipmentSlot.CHEST).getItem(); + + //Uses the same colors as the dojo stuff + return switch (item) { + case Item i when i == Items.DIAMOND_CHESTPLATE -> 0x00ffff; + case Item i when i == Items.GOLDEN_CHESTPLATE -> 0xffd700; + case Item i when i == Items.IRON_CHESTPLATE -> 0xc0c0c0; + case Item i when i == Items.LEATHER_CHESTPLATE -> 0xa52a2a; + + default -> MobGlow.NO_GLOW; + }; + } + + return MobGlow.NO_GLOW; + } + + public static boolean isInZombieShootout() { + if (ChivalrousCarnival.isInCarnival() && SkyblockerConfigManager.get().helpers.carnival.zombieShootoutHelper && CLIENT.player != null) { + BlockPos pos = CLIENT.player.getBlockPos(); + + return SHOOTING_BOX.contains(pos.getX(), pos.getY(), pos.getZ()); + } + + return false; + } +} diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java index 909eea7e88..91469c381a 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -4,6 +4,8 @@ import de.hysky.skyblocker.annotations.Init; import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.config.configs.SlayersConfig; +import de.hysky.skyblocker.skyblock.carnival.CatchAFish; +import de.hysky.skyblocker.skyblock.carnival.ZombieShootout; import de.hysky.skyblocker.skyblock.crimson.dojo.DojoManager; import de.hysky.skyblocker.skyblock.crimson.kuudra.Kuudra; import de.hysky.skyblocker.skyblock.dungeon.DungeonScore; @@ -143,6 +145,10 @@ private static int computeMobGlow(Entity entity) { case WitherSkeletonEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); case ZombifiedPiglinEntity e when SkyblockerConfigManager.get().slayers.highlightBosses == SlayersConfig.HighlightSlayerEntities.GLOW && SlayerManager.isInSlayerType(SlayerType.DEMONLORD) && e.distanceTo(MinecraftClient.getInstance().player) <= 15 -> AttunementColors.getColor(e); + //Chivalrous Carnival + case ZombieEntity zombie when ZombieShootout.isInZombieShootout() -> ZombieShootout.getZombieGlowColor(zombie); + case ArmorStandEntity armorStand when CatchAFish.isInCatchAFish() -> CatchAFish.getFishGlowColor(armorStand); + default -> NO_GLOW; }; } diff --git a/src/main/java/de/hysky/skyblocker/utils/Area.java b/src/main/java/de/hysky/skyblocker/utils/Area.java new file mode 100644 index 0000000000..d15f417b46 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/utils/Area.java @@ -0,0 +1,24 @@ +package de.hysky.skyblocker.utils; + +import java.util.Arrays; + +/** + * An area of a Skyblock Island. + */ +public enum Area { + CARNIVAL("Carnival"), + UNKNOWN("Unknown"); + + private final String name; + + Area(String name) { + this.name = name; + } + + public static Area from(String name) { + return Arrays.stream(values()) + .filter(area -> name.equals(area.name)) + .findFirst() + .orElse(UNKNOWN); + } +} diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java index 1d87fe1170..972abd3c45 100644 --- a/src/main/java/de/hysky/skyblocker/utils/Utils.java +++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java @@ -67,6 +67,11 @@ public class Utils { */ @NotNull private static Location location = Location.UNKNOWN; + /** + * Current Skyblock island area. + */ + @NotNull + private static Area area = Area.UNKNOWN; /** * The profile name parsed from the player list. */ @@ -171,6 +176,16 @@ public static Location getLocation() { return location; } + /** + * Note: Under no circumstances should you skip checking the location if you also need the area. + * + * @return the area parsed from the scoreboard. + */ + @NotNull + public static Area getArea() { + return area; + } + /** * Can be used to restrict features to being active only on the Alpha network. * @@ -348,11 +363,22 @@ private static void updateScoreboard(MinecraftClient client) { STRING_SCOREBOARD.addAll(stringLines); Utils.updatePurse(); SlayerManager.getSlayerBossInfo(true); + updateArea(); } catch (NullPointerException e) { //Do nothing } } + //TODO add event in the future + private static void updateArea() { + if (isOnSkyblock) { + String areaName = getIslandArea().replaceAll("[⏣ф]", "").strip(); + area = Area.from(areaName); + } else { + area = Area.UNKNOWN; + } + } + public static void updatePurse() { STRING_SCOREBOARD.stream().filter(s -> s.contains("Piggy:") || s.contains("Purse:")).findFirst().ifPresent(purseString -> { Matcher matcher = PURSE.matcher(purseString); @@ -389,6 +415,7 @@ private static void onDisconnect() { gameType = ""; locationRaw = ""; location = Location.UNKNOWN; + area = Area.UNKNOWN; map = ""; } diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json index 3e6b5d30b6..08ff3e06a8 100644 --- a/src/main/resources/assets/skyblocker/lang/en_us.json +++ b/src/main/resources/assets/skyblocker/lang/en_us.json @@ -374,6 +374,12 @@ "skyblocker.config.helpers.bazaar.enableBazaarHelper": "Enable Bazaar Helper", "skyblocker.config.helpers.bazaar.enableBazaarHelper.@Tooltip": "Draws icons on top of orders to explain the current state of the order.\n\n%s: Order is going to expire soon\n%s: Order has expired\n%s: Order is filled to some degree and there are items/coins to claim\n%s: Order is filled", + "skyblocker.config.helpers.carnival": "Chivalrous Carnival", + "skyblocker.config.helpers.carnival.catchAFishHelper": "Catch a Fish Helper", + "skyblocker.config.helpers.carnival.catchAFishHelper.@Tooltip": "Makes golden fish glow.", + "skyblocker.config.helpers.carnival.zombieShootoutHelper": "Zombie Shootout Helper", + "skyblocker.config.helpers.carnival.zombieShootoutHelper.@Tooltip": "Outlines lit redstone lamps in red, and applies the glowing effect to zombies where the color depends on the kind of zombie.", + "skyblocker.config.helpers.chocolateFactory": "Chocolate Factory", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper": "Enable Chocolate Factory Helper", "skyblocker.config.helpers.chocolateFactory.enableChocolateFactoryHelper.@Tooltip": "Highlights the best upgrade when enabled. \n\nThe best upgrade is marked as green, but if you can't afford it, it's marked as yellow while marking the next best upgrade that you can afford as green.",