aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java20
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java47
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/end/BeaconHighlighter.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java98
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java47
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java8
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_ca.json6
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json5
-rw-r--r--src/main/resources/assets/skyblocker/lang/pt_br.json7
-rw-r--r--src/main/resources/assets/skyblocker/lang/tr_tr.json42
-rw-r--r--src/main/resources/assets/skyblocker/lang/zh_cn.json12
13 files changed, 272 insertions, 76 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index 83f41c0b..3fca09ce 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -14,6 +14,7 @@ import de.hysky.skyblocker.skyblock.dungeon.puzzle.waterboard.Waterboard;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager;
import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud;
+import de.hysky.skyblocker.skyblock.end.BeaconHighlighter;
import de.hysky.skyblocker.skyblock.item.*;
import de.hysky.skyblocker.skyblock.item.tooltip.BackpackPreview;
import de.hysky.skyblocker.skyblock.item.tooltip.ItemTooltip;
@@ -135,6 +136,7 @@ public class SkyblockerMod implements ClientModInitializer {
RenderHelper.init();
containerSolverManager.init();
statusBarTracker.init();
+ BeaconHighlighter.init();
Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20);
Scheduler.INSTANCE.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 200);
Scheduler.INSTANCE.scheduleCyclic(LividColor::update, 10);
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
index cff06d32..a7569adb 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
@@ -97,6 +97,7 @@ public class SkyblockerConfig {
public QuickNavItem button10 = new QuickNavItem(true, new ItemData("enchanting_table"), "Enchant Item",
"/etable");
+
@SerialEntry
public QuickNavItem button11 = new QuickNavItem(true, new ItemData("anvil"), "Anvil", "/anvil");
@@ -169,7 +170,7 @@ public class SkyblockerConfig {
@SerialEntry
public boolean hideStatusEffectOverlay = false;
-
+
@SerialEntry
public boolean dontStripSkinAlphaValues = true;
@@ -944,9 +945,20 @@ public class SkyblockerConfig {
public static class Slayer {
@SerialEntry
+ public EndermanSlayer endermanSlayer = new EndermanSlayer();
+
+ @SerialEntry
public VampireSlayer vampireSlayer = new VampireSlayer();
}
+ public static class EndermanSlayer {
+ @SerialEntry
+ public boolean highlightNukekubiHeads = true;
+
+ @SerialEntry
+ public boolean highlightBeacons = true;
+ }
+
public static class VampireSlayer {
@SerialEntry
public boolean enableEffigyWaypoints = true;
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
index 7df95172..19b30937 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
@@ -17,6 +17,26 @@ public class SlayersCategory {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.slayer"))
+ //Enderman Slayer
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.slayer.endermanSlayer"))
+ .collapsed(true)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.slayer.endermanSlayer.highlightNukekubiHeads"))
+ .binding(defaults.slayer.endermanSlayer.highlightNukekubiHeads,
+ () -> config.slayer.endermanSlayer.highlightNukekubiHeads,
+ newValue -> config.slayer.endermanSlayer.highlightNukekubiHeads = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.slayer.endermanSlayer.highlightBeacons"))
+ .binding(defaults.slayer.endermanSlayer.highlightBeacons,
+ () -> config.slayer.endermanSlayer.highlightBeacons,
+ newValue -> config.slayer.endermanSlayer.highlightBeacons = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .build())
+
//Vampire Slayer
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.slayer.vampireSlayer"))
diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
index a8537088..1f56fe34 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
@@ -6,14 +6,18 @@ import com.llamalad7.mixinextras.sugar.Local;
import de.hysky.skyblocker.skyblock.FishingHelper;
import de.hysky.skyblocker.skyblock.dungeon.DungeonScore;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonManager;
+import de.hysky.skyblocker.skyblock.end.BeaconHighlighter;
import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual;
+import de.hysky.skyblocker.utils.SlayerUtils;
import de.hysky.skyblocker.utils.Utils;
+import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityStatuses;
import net.minecraft.entity.ItemEntity;
import net.minecraft.entity.LivingEntity;
+import net.minecraft.network.packet.s2c.play.BlockUpdateS2CPacket;
import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket;
import net.minecraft.network.packet.s2c.play.ParticleS2CPacket;
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
@@ -27,13 +31,17 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class ClientPlayNetworkHandlerMixin {
-
- @Inject(method = "onPlaySound", at = @At("RETURN"))
- private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) {
- FishingHelper.onSound(packet);
+ @Inject(method = "onBlockUpdate", at = @At("RETURN"))
+ private void skyblocker$onBlockUpdate(BlockUpdateS2CPacket packet, CallbackInfo ci) {
+ if (Utils.isInTheEnd() && SlayerUtils.isInSlayer()) {
+ BeaconHighlighter.beaconPositions.remove(packet.getPos());
+ if (packet.getState().isOf(Blocks.BEACON)) {
+ BeaconHighlighter.beaconPositions.add(packet.getPos());
+ }
+ }
}
- @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "STORE", ordinal = 0))
+ @ModifyVariable(method = "onItemPickupAnimation", at = @At(value = "STORE", ordinal = 0))
private ItemEntity skyblocker$onItemPickup(ItemEntity itemEntity, @Local LivingEntity collector) {
DungeonManager.onItemPickup(itemEntity, collector, collector == MinecraftClient.getInstance().player);
return itemEntity;
@@ -44,14 +52,25 @@ public abstract class ClientPlayNetworkHandlerMixin {
return !Utils.isOnHypixel();
}
+ @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;"))
+ private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) {
+ if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) DungeonScore.handleEntityDeath(entity);
+ return entity;
+ }
+
@WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false))
private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg1, Object arg2) {
return !Utils.isOnHypixel();
}
- @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false))
- private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) {
- return !Utils.isOnHypixel();
+ @Inject(method = "onPlaySound", at = @At("RETURN"))
+ private void skyblocker$onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) {
+ FishingHelper.onSound(packet);
+ }
+
+ @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false))
+ private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) {
+ return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion"));
}
@WrapWithCondition(method = { "onScoreboardScoreUpdate", "onScoreboardScoreReset" }, at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false))
@@ -59,19 +78,13 @@ public abstract class ClientPlayNetworkHandlerMixin {
return !Utils.isOnHypixel();
}
- @WrapWithCondition(method = "warnOnUnknownPayload", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false))
- private boolean skyblocker$dropBadlionPacketWarnings(Logger instance, String message, Object identifier) {
- return !(Utils.isOnHypixel() && ((Identifier) identifier).getNamespace().equals("badlion"));
+ @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false))
+ private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) {
+ return !Utils.isOnHypixel();
}
@Inject(method = "onParticle", at = @At("RETURN"))
private void skyblocker$onParticle(ParticleS2CPacket packet, CallbackInfo ci) {
MythologicalRitual.onParticle(packet);
}
-
- @ModifyExpressionValue(method = "onEntityStatus", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/packet/s2c/play/EntityStatusS2CPacket;getEntity(Lnet/minecraft/world/World;)Lnet/minecraft/entity/Entity;"))
- private Entity skyblocker$onEntityDeath(Entity entity, @Local(argsOnly = true) EntityStatusS2CPacket packet) {
- if (packet.getStatus() == EntityStatuses.PLAY_DEATH_SOUND_OR_ADD_PROJECTILE_HIT_PARTICLES) DungeonScore.handleEntityDeath(entity);
- return entity;
- }
}
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);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index 53c0ff4a..3f07622c 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -90,6 +90,14 @@ public class Utils {
return getLocationRaw().equals(TheRift.LOCATION);
}
+ /**
+ * @return if the player is in the end island
+ */
+ public static boolean isInTheEnd() {
+ // /locraw returns "combat_3" when in The End
+ return getLocationRaw().equals("combat_3");
+ }
+
public static boolean isInjected() {
return isInjected;
}
diff --git a/src/main/resources/assets/skyblocker/lang/en_ca.json b/src/main/resources/assets/skyblocker/lang/en_ca.json
index da8193d1..416f9d9b 100644
--- a/src/main/resources/assets/skyblocker/lang/en_ca.json
+++ b/src/main/resources/assets/skyblocker/lang/en_ca.json
@@ -27,5 +27,9 @@
"text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.lossColor": "Loss Colour",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip": "Displays a coloured background behind an item, the colour represents the item's rarity.",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticTooltip.@Tooltip": "Displays the type of exotic below the item's name if an armour piece is exotic.",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow": "Enable Livid Colour Glow"
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow": "Enable Livid Colour Glow",
+ "skyblocker.tips.customArmorDyeColors": "Apply a custom dye colour to your leather armour with /skyblocker custom dyeColor",
+ "skyblocker.tips.customArmorTrims": "You can set custom armour trims on your armour using /skyblocker custom armorTrim.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorTitle": "Enable Livid Colour Title",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorTitle.@Tooltip": "Display the livid colour in the title during the Livid boss fight."
}
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 7afe4196..527205cf 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -311,6 +311,9 @@
"text.autoconfig.skyblocker.option.messages.hideDeath": "Hide Player Death Messages",
"text.autoconfig.skyblocker.option.messages.hideDeath.@Tooltip": "Filters the player death messages from chat.",
"text.autoconfig.skyblocker.category.slayer": "Slayers",
+ "text.autoconfig.skyblocker.option.slayer.endermanSlayer": "[Beta] Enderman Slayer",
+ "text.autoconfig.skyblocker.option.slayer.endermanSlayer.highlightNukekubiHeads": "Nukekubi Head Highlighting",
+ "text.autoconfig.skyblocker.option.slayer.endermanSlayer.highlightBeacons": "Beacon Highlighting",
"text.autoconfig.skyblocker.option.slayer.vampireSlayer": "Vampire Slayer",
"text.autoconfig.skyblocker.option.slayer.vampireSlayer.enableEffigyWaypoints": "Enable Effigy Waypoints",
"text.autoconfig.skyblocker.option.slayer.vampireSlayer.compactEffigyWaypoints": "Compact Effigy Waypoints",
@@ -456,4 +459,4 @@
"skyblocker.partyFinder.join": "Click to join",
"emi.category.skyblocker.skyblock": "Skyblock"
-} \ No newline at end of file
+}
diff --git a/src/main/resources/assets/skyblocker/lang/pt_br.json b/src/main/resources/assets/skyblocker/lang/pt_br.json
index 11242adf..02e52b02 100644
--- a/src/main/resources/assets/skyblocker/lang/pt_br.json
+++ b/src/main/resources/assets/skyblocker/lang/pt_br.json
@@ -105,7 +105,7 @@
"text.autoconfig.skyblocker.option.general.itemTooltip.avg": "Tipo Mediano",
"text.autoconfig.skyblocker.option.general.itemTooltip.avg.ONE_DAY": "Preço de 1 dia",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Ativar Preço de compra/venda do Bazar",
- "text.autoconfig.skyblocker.option.messages.hideAOTE": "Esconder Mensagens do AOTE",
+ "text.autoconfig.skyblocker.option.messages.hideAOTE": "Esconder Mensagens da Habilidade de Teleporte",
"text.autoconfig.skyblocker.option.messages.hideTeleportPad": "Esconder Mensagens do Pad de Teleporte",
"text.autoconfig.skyblocker.option.messages.hideShowOff": "Esconder Mensagens de Show Off",
"text.autoconfig.skyblocker.option.slayer.vampireSlayer.effigyUpdateFrequency": "Frequência de Atualização (Ticks) de Waypoints de Effigy",
@@ -280,5 +280,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.includeKismet.@Tooltip": "Se ativado, o preço de uma Kismet usada será subtraído no cálculo da margem de lucro",
"text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit.includeEssence": "Incluir essência",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.showSecretText": "Exibir texto secreto",
- "text.autoconfig.skyblocker.option.quickNav.button.clickEvent": "Evento ao clicar"
+ "text.autoconfig.skyblocker.option.quickNav.button.clickEvent": "Evento ao clicar",
+ "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "Ativar Waypoints",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "Tipo de Waypoint",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote": "\n\n\nEssa opção não aplica para todos os waypoints. Alguns waypoints como waypoints secretos tem seu próprio opção de tipo de waypoint."
}
diff --git a/src/main/resources/assets/skyblocker/lang/tr_tr.json b/src/main/resources/assets/skyblocker/lang/tr_tr.json
index 362c7e55..b46463fb 100644
--- a/src/main/resources/assets/skyblocker/lang/tr_tr.json
+++ b/src/main/resources/assets/skyblocker/lang/tr_tr.json
@@ -50,7 +50,7 @@
"text.autoconfig.skyblocker.category.general": "Genel",
"text.autoconfig.skyblocker.option.general.bars": "Can, Mana, Defans ve XP Barları",
"text.autoconfig.skyblocker.option.general.bars.enableBars": "Barları Etkinleştir",
- "text.autoconfig.skyblocker.option.general.bars.barpositions": "Bar Konumları",
+ "text.autoconfig.skyblocker.option.general.bars.barpositions": "Çubuk Konumlarını Ayarla",
"text.autoconfig.skyblocker.option.general.bars.barpositions.NONE": "Devre dışı",
"text.autoconfig.skyblocker.option.general.bars.barpositions.healthBarPosition": "Can barı konumu",
"text.autoconfig.skyblocker.option.general.bars.barpositions.manaBarPosition": "Mana barı konumu",
@@ -61,5 +61,43 @@
"text.autoconfig.skyblocker.option.general.fishing": "Balık Tutma Yardımcısı",
"text.autoconfig.skyblocker.option.general.fishing.enableFishingHelper": "Balık tutma yardımcısını aktifleştir",
"text.autoconfig.skyblocker.category.messages": "Mesajlar",
- "text.autoconfig.skyblocker.option.messages.hideImplosion": "Implosion mesajını filtrele"
+ "text.autoconfig.skyblocker.option.messages.hideImplosion": "Implosion mesajını filtrele",
+ "key.skyblocker.toggleB": "Tab HUD'unda B ekranını aç",
+ "key.skyblocker.toggleA": "Tab HUD'unda A ekranını aç",
+ "text.autoconfig.skyblocker.option.general.mythologicalRitual": "Mitolojik Ayin Yardımcısı",
+ "text.autoconfig.skyblocker.option.general.mythologicalRitual.enableMythologicalRitualHelper": "Mitolojik Ayin Yardımcısını Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.fairySouls.highlightFoundSouls": "Bulunmuş peri ruhlarını göster",
+ "text.autoconfig.skyblocker.option.general.fairySouls.highlightOnlyNearbySouls": "Sadece yakındaki peri ruhlarını göster",
+ "text.autoconfig.skyblocker.option.general.fairySouls.highlightOnlyNearbySouls.@Tooltip": "Etkinleştirildiğinde sadece 50 blokluk mesafedeki peri ruhları gösterilir",
+ "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER2": "Katman 2",
+ "text.autoconfig.skyblocker.option.general.shortcuts.config": "Kısayol Ayarları...",
+ "text.autoconfig.skyblocker.option.general.acceptReparty": "Tekrar parti davetini otomatik kabul et",
+ "text.autoconfig.skyblocker.option.general.experiments.enableUltrasequencerSolver": "Ultrasekans Çözücüsünü Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.experiments.enableSuperpairsSolver": "Süperçiftler Çözücüsünü Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.experiments": "Deney Çözücü",
+ "text.autoconfig.skyblocker.option.general.experiments.enableChronomatronSolver": "Chronomatron Çözücüsünü Etkinleştir",
+ "key.skyblocker.defaultTgl": "Tab HUD'unda varsayılan görünüme geç",
+ "text.autoconfig.skyblocker.option.general.bars.barpositions.RIGHT": "Sağ",
+ "text.autoconfig.skyblocker.option.general.fairySouls": "Peri Ruhları Yardımcısı",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableShortcuts.@Tooltip": "Vanilla dahil her yerde çalışır! Kısayolları \"/skyblocker shortcuts\" ile düzenleyebilirsiniz. Bu seçeneğin etki göstermesi için sıradaki seçeneklerden en az birinin etkinleştirilmiş olması gerekir.",
+ "text.autoconfig.skyblocker.option.general.shortcuts": "Kısayollar",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandShortcuts": "Komut Kısayollarını Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableShortcuts": "Kısayolları Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandShortcuts.@Tooltip": "Sadece bir kelimeden oluşan komutlar için kısayollar. Kısayolları \"/skyblocker shortcuts\" ile düzenleyebilirsiniz. Bu seçeneğin etki göstermesi için kısayolların etkinleştirilmiş olması gerekir.",
+ "text.autoconfig.skyblocker.option.general.etherwarpOverlay": "Etherwarp Kaplaması",
+ "text.autoconfig.skyblocker.option.general.fairySouls.enableFairySoulsHelper": "Peri Ruhları Yardımcısını Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts": "Komut Argüman Kısayollarını Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.waypoints": "İşaret Noktaları",
+ "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "İşaret Noktalarını Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "İşaret Noktası Tipi",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: İşaret noktasını renklendirir ve fener ışını gösterir\n\nOutlined Waypoint: İşaret noktasını ve kenar çizgilerini gösterir.\n\nHighlight: Sadece işaret noktasını renklendirir.\n\nOutlined Highlight: İşaret noktasını renklendirir ve kenar çizgilerini gösterir.\n\nOutline: Sadece kenar çizgilerini gösterir.",
+ "text.autoconfig.skyblocker.option.general.itemCooldown": "Eşya Bekleme Süresi",
+ "text.autoconfig.skyblocker.option.general.itemCooldown.enableItemCooldowns": "Eşya Bekleme Süresini Etkinleştir",
+ "text.skyblocker.open": "Aç",
+ "text.skyblocker.quit_config": "Değişikler Kaydedilmedi",
+ "text.skyblocker.quit_config_sure": "Ayarları düzenlemekten çıkmak istediğinize emin misiniz? Yaptığınız değişikler kaydedilmeyecek!",
+ "text.skyblocker.quit_discard": "Çık & Değişiklikleri Yoksay",
+ "text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER1": "Katman 1",
+ "text.autoconfig.skyblocker.option.general.enableTips": "Tüyoları Etkinleştir",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts.@Tooltip": "Birden fazla kelime/argümandan oluşan komutların birden fazla komut/argümanını değiştiren kısayollar. Kısayolları \"/skyblocker shortcuts\" ile düzenleyebilirsiniz. Bu seçeneğin etki göstermesi için kısayolların etkinleştirilmiş olması gerekir."
}
diff --git a/src/main/resources/assets/skyblocker/lang/zh_cn.json b/src/main/resources/assets/skyblocker/lang/zh_cn.json
index a268d5a5..4d058bf1 100644
--- a/src/main/resources/assets/skyblocker/lang/zh_cn.json
+++ b/src/main/resources/assets/skyblocker/lang/zh_cn.json
@@ -113,7 +113,7 @@
"skyblocker.fairySouls.markAllFound": "将当前岛屿上的全部仙女之魂标记为已发现",
"text.autoconfig.skyblocker.option.slayer.vampireSlayer.steakStakeUpdateFrequency.@Tooltip": "值越小,更新越频繁(可能会导致卡顿)",
"text.autoconfig.skyblocker.option.general.shortcuts": "更精简的命令",
- "text.autoconfig.skyblocker.option.general.shortcuts.enableShortcuts.@Tooltip": "使用 \"/skyblocker shortcuts\" 以编辑命令的精简版本, 以下选项必须至少启用之一方可有效. (仅在Hypixel服务器可用)",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableShortcuts.@Tooltip": "使用 \"/skyblocker shortcuts\" 以编辑命令的精简版本, 以下选项必须至少启用之一方可有效. (此功能在空岛生存外也可使用)",
"text.autoconfig.skyblocker.option.general.teleportOverlay": "传送类技能目标位置显示",
"text.autoconfig.skyblocker.option.general.teleportOverlay.enableTeleportOverlays": "启用传送类技能目标位置显示",
"text.autoconfig.skyblocker.option.general.teleportOverlay.enableWeirdTransmission": "启用 Weird Transmission 目标位置显示",
@@ -149,5 +149,13 @@
"text.skyblocker.quit_config_sure": "确定退出吗? 你的修改将不会被保存!",
"text.autoconfig.skyblocker.option.general.wikiLookup": "查阅 wiki",
"text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki": "使用Hypixel官方 Wiki",
- "text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki.@Tooltip": "在查阅时使用Hypixel 官方 wiki 代替 Fandom wiki"
+ "text.autoconfig.skyblocker.option.general.wikiLookup.officialWiki.@Tooltip": "在查阅时使用Hypixel 官方 wiki 代替 Fandom wiki",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableObtainedDate": "显示获取时间",
+ "text.autoconfig.skyblocker.option.general.shortcuts.enableCommandShortcuts.@Tooltip": "此功能可用较短的别名替换较长的原始命令,使用 \"/skyblocker shortcuts\" 以编辑. (“更精简的命令”功能必须启用才可生效)",
+ "text.autoconfig.skyblocker.option.general.waypoints": "路径点",
+ "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "启用路径点",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "路径点类型",
+ "text.skyblocker.open": "开启",
+ "text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup": "启用 wiki 查阅功能",
+ "text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup.@Tooltip": "指针悬停于物品之下按 F4 键打开 wiki 相关条目"
}