diff options
Diffstat (limited to 'src/main/java/de/hysky/skyblocker/skyblock')
3 files changed, 135 insertions, 50 deletions
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/end/BeaconHighlighter.java b/src/main/java/de/hysky/skyblocker/skyblock/end/BeaconHighlighter.java new file mode 100644 index 00000000..d2269482 --- /dev/null +++ b/src/main/java/de/hysky/skyblocker/skyblock/end/BeaconHighlighter.java @@ -0,0 +1,40 @@ +package de.hysky.skyblocker.skyblock.end; + +import de.hysky.skyblocker.config.SkyblockerConfigManager; +import de.hysky.skyblocker.utils.Utils; +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.util.math.BlockPos; + +import java.util.ArrayList; +import java.util.List; + +public class BeaconHighlighter { + public static final List<BlockPos> beaconPositions = new ArrayList<>(); + + /** + * Initializes the beacon highlighting system. + * {@link BeaconHighlighter#render(WorldRenderContext)} is called after translucent rendering. + */ + public static void init() { + WorldRenderEvents.AFTER_TRANSLUCENT.register(BeaconHighlighter::render); + } + + /** + * Renders the beacon glow around it. It is rendered in a red color with 50% opacity, and + * is visible through walls. + * + * @param context An instance of WorldRenderContext for the RenderHelper to use + */ + public static void render(WorldRenderContext context) { + if (Utils.isInTheEnd() && SkyblockerConfigManager.get().slayer.endermanSlayer.highlightBeacons) + beaconPositions.forEach((position) -> RenderHelper.renderFilled( + context, + position, + new float[]{1.0f, 0.0f, 0.0f}, + 0.5f, + 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 fa9f6e4f..d0d58606 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java @@ -1,66 +1,81 @@ package de.hysky.skyblocker.skyblock.entity; -import java.util.List; - import de.hysky.skyblocker.config.SkyblockerConfigManager; import de.hysky.skyblocker.skyblock.dungeon.LividColor; +import de.hysky.skyblocker.utils.SlayerUtils; import de.hysky.skyblocker.utils.Utils; import de.hysky.skyblocker.utils.render.culling.OcclusionCulling; import net.minecraft.entity.Entity; import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.passive.BatEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtElement; import net.minecraft.predicate.entity.EntityPredicates; import net.minecraft.util.Formatting; import net.minecraft.util.math.Box; import net.minecraft.world.World; +import java.util.List; + public class MobGlow { public static boolean shouldMobGlow(Entity entity) { Box box = entity.getBoundingBox(); - if (!entity.isInvisible() && OcclusionCulling.getReducedCuller().isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) { + if (OcclusionCulling.getReducedCuller().isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) { String name = entity.getName().getString(); - // Dungeons - if (Utils.isInDungeons()) { + if (!entity.isInvisible()) { + + // Dungeons + if (Utils.isInDungeons()) { - // Minibosses - if (entity instanceof PlayerEntity) { - switch (name) { - case "Lost Adventurer", "Shadow Assassin", "Diamond Guy": return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow; - case "Arcade Livid", "Crossed Livid", "Doctor Livid", "Frog Livid", "Hockey Livid", - "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid": return LividColor.shouldGlow(name); + // Minibosses + if (entity instanceof PlayerEntity) { + switch (name) { + case "Lost Adventurer", "Shadow Assassin", "Diamond Guy": return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow; + case "Arcade Livid", "Crossed Livid", "Doctor Livid", "Frog Livid", "Hockey Livid", + "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid": return LividColor.shouldGlow(name); + } } - } - // Regular Mobs - if (!(entity instanceof ArmorStandEntity)) { - List<ArmorStandEntity> armorStands = getArmorStands(entity.getWorld(), box); + // Regular Mobs + if (!(entity instanceof ArmorStandEntity)) { + List<ArmorStandEntity> armorStands = getArmorStands(entity.getWorld(), box); - if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow; - } + if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) + return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow; + } - // Bats - return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow && entity instanceof BatEntity; - } + // Bats + return SkyblockerConfigManager.get().locations.dungeons.starredMobGlow && entity instanceof BatEntity; + } - // Rift - if (Utils.isInTheRift()) { - if (entity instanceof PlayerEntity) { - switch (name) { - // They have a space in their name for some reason... - case "Blobbercyst ": return SkyblockerConfigManager.get().locations.rift.blobbercystGlow; + // Rift + if (Utils.isInTheRift()) { + if (entity instanceof PlayerEntity) { + switch (name) { + // They have a space in their name for some reason... + case "Blobbercyst ": return SkyblockerConfigManager.get().locations.rift.blobbercystGlow; + } } } } + + // Enderman Slayer + // Highlights Nukekubi Heads + return SkyblockerConfigManager.get().slayer.endermanSlayer.highlightNukekubiHeads + && SlayerUtils.isInSlayer() + && entity instanceof ArmorStandEntity armorStandEntity + && isNukekubiHead(armorStandEntity); } return false; } private static List<ArmorStandEntity> getArmorStands(World world, Box box) { - return world.getEntitiesByClass(ArmorStandEntity.class, box.expand(0, 2, 0), EntityPredicates.NOT_MOUNTED); + return world.getEntitiesByClass(ArmorStandEntity.class, box.expand(0, 2, 0), EntityPredicates.NOT_MOUNTED); } public static int getGlowColor(Entity entity) { @@ -72,12 +87,39 @@ public class MobGlow { case "Shadow Assassin" -> 0x5b2cb2; case "Diamond Guy" -> 0x57c2f7; case "Arcade Livid", "Crossed Livid", "Doctor Livid", "Frog Livid", "Hockey Livid", - "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid" -> LividColor.getGlowColor(name); + "Purple Livid", "Scream Livid", "Smile Livid", "Vendetta Livid" -> LividColor.getGlowColor(name); case "Blobbercyst " -> Formatting.GREEN.getColorValue(); default -> 0xf57738; }; } + // copypaste nukekebi head logic + if (entity instanceof ArmorStandEntity armorStandEntity && isNukekubiHead(armorStandEntity)) return 0x990099; + return 0xf57738; } + + private static boolean isNukekubiHead(ArmorStandEntity entity) { + for (ItemStack armorItem : entity.getArmorItems()) { + // hacky way to check if an item is a player head w/o + // some shenanigans + if (!armorItem.toString().startsWith("1 player_head")) + continue; + + // eb07594e2df273921a77c101d0bfdfa1115abed5b9b2029eb496ceba9bdbb4b3 is texture id for the nukekubi head, + // compare against it to exclusively find armorstands that are nukekubi heads + NbtCompound skullOwner = armorItem.getSubNbt("SkullOwner"); + if (skullOwner != null) { + // get the texture of the nukekubi head item itself and compare it + String texture = skullOwner + .getCompound("Properties") + .getList("textures", NbtElement.COMPOUND_TYPE) + .getCompound(0) + .getString("Value"); + + return texture.contains("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWIwNzU5NGUyZGYyNzM5MjFhNzdjMTAxZDBiZmRmYTExMTVhYmVkNWI5YjIwMjllYjQ5NmNlYmE5YmRiYjRiMyJ9fX0="); + } + } + return false; + } } diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java index 472e6d61..24dcc229 100644 --- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java +++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java @@ -1,9 +1,5 @@ package de.hysky.skyblocker.skyblock.tabhud.widget; -import java.util.HashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import de.hysky.skyblocker.skyblock.tabhud.util.Ico; import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr; import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent; @@ -14,6 +10,12 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static java.util.Map.entry; + // this widget shows info about the current jacob's contest (garden only) public class JacobsContestWidget extends Widget { @@ -22,23 +24,20 @@ public class JacobsContestWidget extends Widget { Formatting.BOLD); //TODO Properly match the contest placement and display it - private static final Pattern CROP_PATTERN = Pattern.compile("(?:☘|○) (?<crop>[A-Za-z ]+)(?:.+)?"); + private static final Pattern CROP_PATTERN = Pattern.compile("(?<fortune>[☘○]) (?<crop>[A-Za-z ]+).*"); - private static final HashMap<String, ItemStack> FARM_DATA = new HashMap<>(); - - // again, there HAS to be a better way to do this - static { - FARM_DATA.put("Wheat", new ItemStack(Items.WHEAT)); - FARM_DATA.put("Sugar Cane", new ItemStack(Items.SUGAR_CANE)); - FARM_DATA.put("Carrot", new ItemStack(Items.CARROT)); - FARM_DATA.put("Potato", new ItemStack(Items.POTATO)); - FARM_DATA.put("Melon", new ItemStack(Items.MELON_SLICE)); - FARM_DATA.put("Pumpkin", new ItemStack(Items.PUMPKIN)); - FARM_DATA.put("Cocoa Beans", new ItemStack(Items.COCOA_BEANS)); - FARM_DATA.put("Nether Wart", new ItemStack(Items.NETHER_WART)); - FARM_DATA.put("Cactus", new ItemStack(Items.CACTUS)); - FARM_DATA.put("Mushroom", new ItemStack(Items.RED_MUSHROOM)); - } + private static final Map<String, ItemStack> FARM_DATA = Map.ofEntries( + entry("Wheat", new ItemStack(Items.WHEAT)), + entry("Sugar Cane", new ItemStack(Items.SUGAR_CANE)), + entry("Carrot", new ItemStack(Items.CARROT)), + entry("Potato", new ItemStack(Items.POTATO)), + entry("Melon", new ItemStack(Items.MELON_SLICE)), + entry("Pumpkin", new ItemStack(Items.PUMPKIN)), + entry("Cocoa Beans", new ItemStack(Items.COCOA_BEANS)), + entry("Nether Wart", new ItemStack(Items.NETHER_WART)), + entry("Cactus", new ItemStack(Items.CACTUS)), + entry("Mushroom", new ItemStack(Items.RED_MUSHROOM)) + ); public JacobsContestWidget() { super(TITLE, Formatting.YELLOW.getColorValue()); @@ -54,7 +53,7 @@ public class JacobsContestWidget extends Widget { this.addSimpleIcoText(Ico.CLOCK, "Starts in:", Formatting.GOLD, 76); } - TableComponent tc = new TableComponent(1, 3, Formatting.YELLOW .getColorValue()); + TableComponent tc = new TableComponent(1, 3, Formatting.YELLOW.getColorValue()); for (int i = 77; i < 80; i++) { Matcher item = PlayerListMgr.regexAt(i, CROP_PATTERN); @@ -63,7 +62,11 @@ public class JacobsContestWidget extends Widget { itc = new IcoTextComponent(); } else { String cropName = item.group("crop").trim(); //Trimming is needed because during a contest the space separator will be caught - itc = new IcoTextComponent(FARM_DATA.get(cropName), Text.of(cropName)); + if (item.group("fortune").equals("☘")) { + itc = new IcoTextComponent(FARM_DATA.get(cropName), Text.literal(cropName).append(Text.literal(" ☘").formatted(Formatting.GOLD))); + } else { + itc = new IcoTextComponent(FARM_DATA.get(cropName), Text.of(cropName)); + } } tc.addToCell(0, i - 77, itc); } |