aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/hysky/skyblocker/SkyblockerMod.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java92
-rw-r--r--src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java34
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java46
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java28
-rw-r--r--src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/Debug.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java18
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java31
-rw-r--r--src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java43
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java15
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java64
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java56
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java99
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java83
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java42
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java99
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java40
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java108
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java55
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java11
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java3
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java12
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java13
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java9
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java6
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java27
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java53
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java7
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/JacobsContestWidget.java20
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java)107
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java)4
-rw-r--r--src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java (renamed from src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java)78
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/ApiUtils.java14
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Constants.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Http.java44
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java23
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/Utils.java2
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java1
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java118
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java36
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java10
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java4
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java44
-rw-r--r--src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java40
-rw-r--r--src/main/resources/assets/skyblocker/dungeons/secretlocations.json6
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_ca.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/en_us.json28
-rw-r--r--src/main/resources/assets/skyblocker/lang/fr_fr.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/pt_br.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/ru_ru.json4
-rw-r--r--src/main/resources/assets/skyblocker/lang/zh_cn.json4
-rw-r--r--src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png (renamed from src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png)bin198 -> 198 bytes
-rw-r--r--src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.pngbin0 -> 502 bytes
-rw-r--r--src/main/resources/skyblocker.mixins.json7
-rw-r--r--src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java79
-rw-r--r--src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java11
-rw-r--r--src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java38
-rw-r--r--src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java70
95 files changed, 1361 insertions, 895 deletions
diff --git a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
index b398e9b6..cbe82667 100644
--- a/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
+++ b/src/main/java/de/hysky/skyblocker/SkyblockerMod.java
@@ -3,8 +3,9 @@ package de.hysky.skyblocker;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.debug.Debug;
import de.hysky.skyblocker.skyblock.*;
-import de.hysky.skyblocker.skyblock.diana.MythologicalRitual;
+import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual;
import de.hysky.skyblocker.skyblock.dungeon.*;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets;
import de.hysky.skyblocker.skyblock.dungeon.secrets.SecretsTracker;
@@ -17,15 +18,17 @@ import de.hysky.skyblocker.skyblock.quicknav.QuickNav;
import de.hysky.skyblocker.skyblock.rift.TheRift;
import de.hysky.skyblocker.skyblock.shortcut.Shortcuts;
import de.hysky.skyblocker.skyblock.special.SpecialEffects;
-import de.hysky.skyblocker.skyblock.spidersden.Relics;
+import de.hysky.skyblocker.skyblock.waypoint.Relics;
import de.hysky.skyblocker.skyblock.tabhud.TabHud;
import de.hysky.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import de.hysky.skyblocker.skyblock.waypoint.FairySouls;
import de.hysky.skyblocker.utils.ApiUtils;
import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.chat.ChatMessageListener;
import de.hysky.skyblocker.utils.discord.DiscordRPCManager;
+import de.hysky.skyblocker.utils.render.RenderHelper;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.gui.ContainerSolverManager;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
@@ -113,6 +116,8 @@ public class SkyblockerMod implements ClientModInitializer {
MuseumItemCache.init();
SecretsTracker.init();
ApiUtils.init();
+ Debug.init();
+ RenderHelper.init();
containerSolverManager.init();
statusBarTracker.init();
Scheduler.INSTANCE.scheduleCyclic(Utils::update, 20);
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
index 145f7ec4..7820dfa4 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/MixinPlugin.java
@@ -1,20 +1,15 @@
package de.hysky.skyblocker.compatibility;
-import java.util.List;
-import java.util.Set;
-
+import net.fabricmc.loader.api.FabricLoader;
import org.objectweb.asm.tree.ClassNode;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
-import net.fabricmc.loader.api.FabricLoader;
+import java.util.List;
+import java.util.Set;
public class MixinPlugin implements IMixinConfigPlugin {
- private static final Logger LOGGER = LoggerFactory.getLogger(MixinPlugin.class);
private static final boolean OPTIFABRIC_LOADED = FabricLoader.getInstance().isModLoaded("optifabric");
- private static final String YACL_VERSION = FabricLoader.getInstance().getModContainer("yet_another_config_lib_v3").get().getMetadata().getVersion().getFriendlyString();
@Override
public void onLoad(String mixinPackage) {
@@ -29,21 +24,8 @@ public class MixinPlugin implements IMixinConfigPlugin {
@Override
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
//OptiFabric Compatibility
- if (mixinClassName.endsWith("WorldRendererMixin") && OPTIFABRIC_LOADED) return false;
-
- //YACL#103 Patch
- if (mixinClassName.endsWith("DoubleFieldControllerMixin") || mixinClassName.endsWith("FloatFieldControllerMixin") || mixinClassName.endsWith("IntegerFieldControllerMixin") || mixinClassName.endsWith("LongFieldControllerMixin") || mixinClassName.endsWith("NumberFieldControllerMixin")) {
- if (YACL_VERSION.equals("3.2.1+1.20.2")) {
- LOGGER.info("[Skyblocker] Applying patch for " + targetClassName + " from " + mixinClassName);
- } else {
- LOGGER.info("[Skyblocker] Skipping patch on " + targetClassName + " due to an Unknown YACL version being found! Version: {}", YACL_VERSION);
-
- return false;
- }
- }
-
- return true;
- }
+ return !mixinClassName.endsWith("WorldRendererMixin") || !OPTIFABRIC_LOADED;
+ }
@Override
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
index b52d6ff5..218eb8d1 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockEmiRecipe.java
@@ -4,7 +4,6 @@ import de.hysky.skyblocker.skyblock.itemlist.SkyblockCraftingRecipe;
import de.hysky.skyblocker.utils.ItemUtils;
import dev.emi.emi.api.recipe.EmiCraftingRecipe;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
-import dev.emi.emi.api.stack.Comparison;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.WidgetHolder;
@@ -16,7 +15,7 @@ public class SkyblockEmiRecipe extends EmiCraftingRecipe {
private final String craftText;
public SkyblockEmiRecipe(SkyblockCraftingRecipe recipe) {
- super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()).comparison(Comparison.compareNbt()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount()));
+ super(recipe.getGrid().stream().map(EmiStack::of).map(EmiIngredient.class::cast).toList(), EmiStack.of(recipe.getResult()), Identifier.of("skyblock", ItemUtils.getItemId(recipe.getResult()).toLowerCase().replace(';', '_') + "_" + recipe.getResult().getCount()));
this.craftText = recipe.getCraftText();
}
diff --git a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
index 6ed6a32a..8dfc5dc9 100644
--- a/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
+++ b/src/main/java/de/hysky/skyblocker/compatibility/emi/SkyblockerEMIPlugin.java
@@ -7,6 +7,7 @@ import dev.emi.emi.api.EmiPlugin;
import dev.emi.emi.api.EmiRegistry;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.render.EmiTexture;
+import dev.emi.emi.api.stack.Comparison;
import dev.emi.emi.api.stack.EmiStack;
import net.minecraft.item.Items;
import net.minecraft.util.Identifier;
@@ -21,7 +22,10 @@ public class SkyblockerEMIPlugin implements EmiPlugin {
@Override
public void register(EmiRegistry registry) {
- ItemRepository.getItemsStream().map(EmiStack::of).forEach(registry::addEmiStack);
+ ItemRepository.getItemsStream().map(EmiStack::of).forEach(emiStack -> {
+ registry.addEmiStack(emiStack);
+ registry.setDefaultComparison(emiStack, Comparison.compareNbt());
+ });
registry.addCategory(SKYBLOCK);
registry.addWorkstation(SKYBLOCK, EmiStack.of(Items.CRAFTING_TABLE));
ItemRepository.getRecipesStream().map(SkyblockEmiRecipe::new).forEach(registry::addRecipe);
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
index 68520cab..1c6bb394 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfig.java
@@ -1,5 +1,6 @@
package de.hysky.skyblocker.config;
+import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.skyblock.item.CustomArmorTrims;
import de.hysky.skyblocker.utils.chat.ChatFilterResult;
import de.hysky.skyblocker.utils.waypoint.Waypoint;
@@ -10,6 +11,7 @@ import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.client.resource.language.I18n;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
+import net.minecraft.util.Identifier;
import java.util.ArrayList;
import java.util.List;
@@ -187,6 +189,9 @@ public class SkyblockerConfig {
public Shortcuts shortcuts = new Shortcuts();
@SerialEntry
+ public Waypoints waypoints = new Waypoints();
+
+ @SerialEntry
public QuiverWarning quiverWarning = new QuiverWarning();
@SerialEntry
@@ -252,8 +257,8 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case DEFAULT -> "Default";
- case ALPHABETICAL -> "Alphabetical";
+ case DEFAULT -> "Default";
+ case ALPHABETICAL -> "Alphabetical";
};
}
}
@@ -291,10 +296,10 @@ public class SkyblockerConfig {
public int toInt() {
return switch (this) {
- case LAYER1 -> 0;
- case LAYER2 -> 1;
- case RIGHT -> 2;
- case NONE -> -1;
+ case LAYER1 -> 0;
+ case LAYER2 -> 1;
+ case RIGHT -> 2;
+ case NONE -> -1;
};
}
}
@@ -347,6 +352,14 @@ public class SkyblockerConfig {
public boolean enableCommandArgShortcuts = true;
}
+ public static class Waypoints {
+ @SerialEntry
+ public boolean enableWaypoints = true;
+
+ @SerialEntry
+ public Waypoint.Type waypointType = Waypoint.Type.WAYPOINT;
+ }
+
public static class QuiverWarning {
@SerialEntry
public boolean enableQuiverWarning = true;
@@ -360,7 +373,7 @@ public class SkyblockerConfig {
public static class Hitbox {
@SerialEntry
- public boolean oldFarmlandHitbox = true;
+ public boolean oldFarmlandHitbox = false;
@SerialEntry
public boolean oldLeverHitbox = false;
@@ -417,8 +430,8 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case HORIZONTAL -> "Horizontal";
- case VERTICAL -> "Vertical";
+ case HORIZONTAL -> "Horizontal";
+ case VERTICAL -> "Vertical";
};
}
}
@@ -429,9 +442,9 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case LEFT -> "Left";
- case RIGHT -> "Right";
- case MIDDLE -> "Middle";
+ case LEFT -> "Left";
+ case RIGHT -> "Right";
+ case MIDDLE -> "Middle";
};
}
}
@@ -484,7 +497,10 @@ public class SkyblockerConfig {
public boolean enableBazaarPrice = true;
@SerialEntry
- public boolean enableMuseumDate = true;
+ public boolean enableObtainedDate = true;
+
+ @SerialEntry
+ public boolean enableMuseumInfo = true;
@SerialEntry
public boolean enableExoticTooltip = true;
@@ -498,9 +514,31 @@ public class SkyblockerConfig {
public boolean itemRarityBackgrounds = false;
@SerialEntry
+ public RarityBackgroundStyle itemRarityBackgroundStyle = RarityBackgroundStyle.CIRCULAR;
+
+ @SerialEntry
public float itemRarityBackgroundsOpacity = 1f;
}
+ public enum RarityBackgroundStyle {
+ CIRCULAR(new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background_circular")),
+ SQUARE(new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background_square"));
+
+ public final Identifier tex;
+
+ RarityBackgroundStyle(Identifier tex) {
+ this.tex = tex;
+ }
+
+ @Override
+ public String toString() {
+ return switch (this) {
+ case CIRCULAR -> "Circular";
+ case SQUARE -> "Square";
+ };
+ }
+ }
+
public static class WikiLookup {
@SerialEntry
public boolean enableWikiLookup = true;
@@ -552,7 +590,7 @@ public class SkyblockerConfig {
@SerialEntry
public int mapY = 2;
-
+
@SerialEntry
public boolean playerSecretsTracker = false;
@@ -587,10 +625,10 @@ public class SkyblockerConfig {
@SerialEntry
public boolean noInitSecretWaypoints = false;
-
+
@SerialEntry
public Waypoint.Type waypointType = Waypoint.Type.WAYPOINT;
-
+
@SerialEntry
public boolean showSecretText = true;
@@ -620,10 +658,10 @@ public class SkyblockerConfig {
@SerialEntry
public boolean enableStonkWaypoints = true;
-
+
@SerialEntry
public boolean enableAotvWaypoints = true;
-
+
@SerialEntry
public boolean enablePearlWaypoints = true;
@@ -659,7 +697,10 @@ public class SkyblockerConfig {
public static class LividColor {
@SerialEntry
- public boolean enableLividColor = true;
+ public boolean enableLividColorGlow = true;
+
+ @SerialEntry
+ public boolean enableLividColorText = true;
@SerialEntry
public String lividColorText = "The livid color is [color]";
@@ -713,9 +754,9 @@ public class SkyblockerConfig {
@Override
public String toString() {
return switch (this) {
- case SIMPLE -> "Simple";
- case FANCY -> "Fancy";
- case CLASSIC -> "Classic";
+ case SIMPLE -> "Simple";
+ case FANCY -> "Fancy";
+ case CLASSIC -> "Classic";
};
}
}
@@ -731,10 +772,13 @@ public class SkyblockerConfig {
public static class Rift {
@SerialEntry
public boolean mirrorverseWaypoints = true;
-
+
+ @SerialEntry
+ public boolean blobbercystGlow = true;
+
@SerialEntry
public boolean enigmaSoulWaypoints = false;
-
+
@SerialEntry
public boolean highlightFoundEnigmaSouls = true;
diff --git a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
index 98c83975..875090ed 100644
--- a/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
+++ b/src/main/java/de/hysky/skyblocker/config/SkyblockerConfigManager.java
@@ -38,11 +38,11 @@ public class SkyblockerConfigManager {
.registerTypeHierarchyAdapter(Identifier.class, new Identifier.Serializer()))
.build())
.build();
-
+
public static SkyblockerConfig get() {
return HANDLER.instance();
}
-
+
/**
* This method is caller sensitive and can only be called by the mod initializer,
* this is enforced.
@@ -51,15 +51,15 @@ public class SkyblockerConfigManager {
if (StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE).getCallerClass() != SkyblockerMod.class) {
throw new RuntimeException("Skyblocker: Called config init from an illegal place!");
}
-
+
HANDLER.load();
ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options")))));
}
-
+
public static void save() {
HANDLER.save();
}
-
+
public static Screen createGUI(Screen parent) {
return YetAnotherConfigLib.create(HANDLER, (defaults, config, builder) -> builder
.title(Text.translatable("text.autoconfig.skyblocker.title"))
@@ -72,7 +72,7 @@ public class SkyblockerConfigManager {
.category(MessageFilterCategory.create(defaults, config))
.category(DiscordRPCCategory.create(defaults, config))).generateScreen(parent);
}
-
+
/**
* Registers an options command with the given name. Used for registering both options and config as valid commands.
*
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
index fcdc3d8d..907291ca 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DiscordRPCCategory.java
@@ -13,7 +13,7 @@ public class DiscordRPCCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.richPresence"))
-
+
//Uncategorized Options
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.richPresence.enableRichPresence"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
index 02913a28..7bb6414c 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DungeonsCategory.java
@@ -23,7 +23,7 @@ public class DungeonsCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons"))
-
+
//Dungeon Secret Waypoints
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints"))
@@ -45,8 +45,8 @@ public class DungeonsCategory {
.flag(OptionFlag.GAME_RESTART)
.build())
.option(Option.<Type>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip")))
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip")))
.binding(defaults.locations.dungeons.secretWaypoints.waypointType,
() -> config.locations.dungeons.secretWaypoints.waypointType,
newValue -> config.locations.dungeons.secretWaypoints.waypointType = newValue)
@@ -146,7 +146,7 @@ public class DungeonsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.build())
-
+
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.dungeonChestProfit"))
.collapsed(true)
@@ -212,7 +212,7 @@ public class DungeonsCategory {
.controller(EnumDropdownControllerBuilder.getFactory(ConfigUtils.FORMATTING_TO_STRING))
.build())
.build())
-
+
//Others
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper"))
@@ -242,8 +242,8 @@ public class DungeonsCategory {
.controller(FloatFieldControllerBuilder::create)
.build())
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretsTracker"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.secretsTracker.@Tooltip")))
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip")))
.binding(defaults.locations.dungeons.playerSecretsTracker,
() -> config.locations.dungeons.playerSecretsTracker,
newValue -> config.locations.dungeons.playerSecretsTracker = newValue)
@@ -301,11 +301,19 @@ public class DungeonsCategory {
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor"))
.collapsed(true)
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor"))
- .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip")))
- .binding(defaults.locations.dungeons.lividColor.enableLividColor,
- () -> config.locations.dungeons.lividColor.enableLividColor,
- newValue -> config.locations.dungeons.lividColor.enableLividColor = newValue)
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow.@Tooltip")))
+ .binding(defaults.locations.dungeons.lividColor.enableLividColorGlow,
+ () -> config.locations.dungeons.lividColor.enableLividColorGlow,
+ newValue -> config.locations.dungeons.lividColor.enableLividColorGlow = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip")))
+ .binding(defaults.locations.dungeons.lividColor.enableLividColorText,
+ () -> config.locations.dungeons.lividColor.enableLividColorText,
+ newValue -> config.locations.dungeons.lividColor.enableLividColorText = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<String>createBuilder()
@@ -317,7 +325,7 @@ public class DungeonsCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Terminal Solvers
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dungeons.terminals"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
index 719cbd79..80d6485b 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/DwarvenMinesCategory.java
@@ -16,7 +16,7 @@ public class DwarvenMinesCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines"))
-
+
//Uncategorized Options
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.enableDrillFuel"))
@@ -39,7 +39,7 @@ public class DwarvenMinesCategory {
newValue -> config.locations.dwarvenMines.solvePuzzler = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
-
+
//Dwarven HUD
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
index 3cbb1b94..be5f0665 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/GeneralCategory.java
@@ -4,6 +4,7 @@ import de.hysky.skyblocker.config.ConfigUtils;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.skyblock.shortcut.ShortcutsConfigScreen;
import de.hysky.skyblocker.utils.render.title.TitleContainerConfigScreen;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import dev.isxander.yacl3.api.*;
import dev.isxander.yacl3.api.controller.FloatFieldControllerBuilder;
import dev.isxander.yacl3.api.controller.FloatSliderControllerBuilder;
@@ -261,6 +262,27 @@ public class GeneralCategory {
.build())
.build())
+ //Waypoints
+ .group(OptionGroup.createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints"))
+ .collapsed(true)
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints"))
+ .binding(defaults.general.waypoints.enableWaypoints,
+ () -> config.general.waypoints.enableWaypoints,
+ newValue -> config.general.waypoints.enableWaypoints = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Waypoint.Type>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip"), Text.translatable("text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote")))
+ .binding(defaults.general.waypoints.waypointType,
+ () -> config.general.waypoints.waypointType,
+ newValue -> config.general.waypoints.waypointType = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
+ .build())
+
//Quiver Warning
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.quiverWarning"))
@@ -350,10 +372,18 @@ public class GeneralCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
- .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate"))
- .binding(defaults.general.itemTooltip.enableMuseumDate,
- () -> config.general.itemTooltip.enableMuseumDate,
- newValue -> config.general.itemTooltip.enableMuseumDate = newValue)
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableObtainedDate"))
+ .binding(defaults.general.itemTooltip.enableObtainedDate,
+ () -> config.general.itemTooltip.enableObtainedDate,
+ newValue -> config.general.itemTooltip.enableObtainedDate = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo.@Tooltip")))
+ .binding(defaults.general.itemTooltip.enableMuseumInfo,
+ () -> config.general.itemTooltip.enableMuseumInfo,
+ newValue -> config.general.itemTooltip.enableMuseumInfo = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
@@ -386,6 +416,14 @@ public class GeneralCategory {
newValue -> config.general.itemInfoDisplay.itemRarityBackgrounds = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
+ .option(Option.<SkyblockerConfig.RarityBackgroundStyle>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle.@Tooltip")))
+ .binding(defaults.general.itemInfoDisplay.itemRarityBackgroundStyle,
+ () -> config.general.itemInfoDisplay.itemRarityBackgroundStyle,
+ newValue -> config.general.itemInfoDisplay.itemRarityBackgroundStyle = newValue)
+ .controller(ConfigUtils::createEnumCyclingListController)
+ .build())
.option(Option.<Float>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundsOpacity"))
.binding(defaults.general.itemInfoDisplay.itemRarityBackgroundsOpacity,
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
index 5e662fcc..0b388d16 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/LocationsCategory.java
@@ -14,7 +14,7 @@ public class LocationsCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.locations"))
-
+
//Barn
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.barn"))
@@ -34,7 +34,7 @@ public class LocationsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.build())
-
+
//The Rift
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift"))
@@ -47,6 +47,14 @@ public class LocationsCategory {
.controller(ConfigUtils::createBooleanController)
.build())
.option(Option.<Boolean>createBuilder()
+ .name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow.@Tooltip")))
+ .binding(defaults.locations.rift.blobbercystGlow,
+ () -> config.locations.rift.blobbercystGlow,
+ newValue -> config.locations.rift.blobbercystGlow = newValue)
+ .controller(ConfigUtils::createBooleanController)
+ .build())
+ .option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints"))
.description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints.@Tooltip")))
.binding(defaults.locations.rift.enigmaSoulWaypoints,
@@ -70,7 +78,7 @@ public class LocationsCategory {
.controller(opt -> IntegerSliderControllerBuilder.create(opt).range(0, 5).step(1))
.build())
.build())
-
+
//Spider's Den
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.locations.spidersDen"))
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
index ba76a903..c63b933d 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/MessageFilterCategory.java
@@ -13,7 +13,7 @@ public class MessageFilterCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.messages"))
-
+
//Uncategorized Options
.option(Option.<ChatFilterResult>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAbility"))
@@ -31,6 +31,7 @@ public class MessageFilterCategory {
.build())
.option(Option.<ChatFilterResult>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAOTE"))
+ .description(OptionDescription.of(Text.translatable("text.autoconfig.skyblocker.option.messages.hideAOTE.@Tooltip")))
.binding(defaults.messages.hideAOTE,
() -> config.messages.hideAOTE,
newValue -> config.messages.hideAOTE = newValue)
diff --git a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
index 775a0ae1..e2684115 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/QuickNavigationCategory.java
@@ -14,7 +14,7 @@ public class QuickNavigationCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.quickNav"))
-
+
//Toggle
.option(Option.<Boolean>createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.enableQuickNav"))
@@ -23,7 +23,7 @@ public class QuickNavigationCategory {
newValue -> config.quickNav.enableQuickNav = newValue)
.controller(ConfigUtils::createBooleanController)
.build())
-
+
//Button 1
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 1))
@@ -71,7 +71,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 2
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 2))
@@ -119,7 +119,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 3
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 3))
@@ -167,7 +167,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 4
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 4))
@@ -215,7 +215,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 5
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 5))
@@ -263,7 +263,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 6
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 6))
@@ -311,7 +311,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 7
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 7))
@@ -359,7 +359,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 8
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 8))
@@ -407,7 +407,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 9
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 9))
@@ -455,7 +455,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 10
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 10))
@@ -503,7 +503,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 11
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 11))
@@ -551,7 +551,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
//Button 12
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.quickNav.button", 12))
@@ -599,7 +599,7 @@ public class QuickNavigationCategory {
.controller(StringControllerBuilder::create)
.build())
.build())
-
+
.build();
}
}
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 2d8b1332..7df95172 100644
--- a/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
+++ b/src/main/java/de/hysky/skyblocker/config/categories/SlayersCategory.java
@@ -16,7 +16,7 @@ public class SlayersCategory {
public static ConfigCategory create(SkyblockerConfig defaults, SkyblockerConfig config) {
return ConfigCategory.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.category.slayer"))
-
+
//Vampire Slayer
.group(OptionGroup.createBuilder()
.name(Text.translatable("text.autoconfig.skyblocker.option.slayer.vampireSlayer"))
@@ -110,7 +110,7 @@ public class SlayersCategory {
.controller(opt -> IntegerSliderControllerBuilder.create(opt).range(1, 10).step(1))
.build())
.build())
-
+
.build();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/debug/Debug.java b/src/main/java/de/hysky/skyblocker/debug/Debug.java
new file mode 100644
index 00000000..1fc22d2a
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/debug/Debug.java
@@ -0,0 +1,14 @@
+package de.hysky.skyblocker.debug;
+
+import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
+import net.fabricmc.loader.api.FabricLoader;
+
+public class Debug {
+ private static final boolean DEBUG_ENABLED = Boolean.parseBoolean(System.getProperty("skyblocker.debug", "false"));
+
+ public static void init() {
+ if (DEBUG_ENABLED || FabricLoader.getInstance().isDevelopmentEnvironment()) {
+ ClientCommandRegistrationCallback.EVENT.register(DumpPlayersCommand::register);
+ }
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java b/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java
new file mode 100644
index 00000000..5f6e0362
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/debug/DumpPlayersCommand.java
@@ -0,0 +1,31 @@
+package de.hysky.skyblocker.debug;
+
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.CommandDispatcher;
+import de.hysky.skyblocker.SkyblockerMod;
+import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.entity.player.PlayerEntity;
+import net.minecraft.text.Text;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
+
+public class DumpPlayersCommand {
+
+ static void register(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
+ dispatcher.register(literal(SkyblockerMod.NAMESPACE)
+ .then(literal("debug")
+ .then(literal("dumpPlayers")
+ .executes(context -> {
+ FabricClientCommandSource source = context.getSource();
+
+ source.getWorld().getEntities().forEach(e -> {
+ if (e instanceof PlayerEntity player) {
+ source.sendFeedback(Text.of("'" + player.getName().getString() + "'"));
+ }
+ });
+
+ return Command.SINGLE_SUCCESS;
+ }))));
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
index f68a4e94..384986ae 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
@@ -3,7 +3,7 @@ package de.hysky.skyblocker.mixin;
import com.llamalad7.mixinextras.injector.WrapWithCondition;
import com.llamalad7.mixinextras.sugar.Local;
import de.hysky.skyblocker.skyblock.FishingHelper;
-import de.hysky.skyblocker.skyblock.diana.MythologicalRitual;
+import de.hysky.skyblocker.skyblock.waypoint.MythologicalRitual;
import de.hysky.skyblocker.skyblock.dungeon.secrets.DungeonSecrets;
import de.hysky.skyblocker.utils.Utils;
import dev.cbyrne.betterinject.annotations.Inject;
diff --git a/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java b/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
index 3a60bfbb..cad7cf38 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/SocialInteractionsPlayerListWidgetMixin.java
@@ -18,7 +18,7 @@ public class SocialInteractionsPlayerListWidgetMixin {
@WrapOperation(method = "setPlayers", at = @At(value = "INVOKE", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;", remap = false))
private Object skyblocker$hideInvalidPlayers(Map<Object, Object> map, Object uuid, Object entry, Operation<Object> operation) {
if (Utils.isOnSkyblock() && !((SocialInteractionsPlayerListEntry) entry).getName().matches("[A-Za-z0-9_]+")) return null;
-
+
return operation.call(map, uuid, entry);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java b/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
index e723c998..42601546 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/WorldRendererMixin.java
@@ -9,25 +9,21 @@ import com.llamalad7.mixinextras.sugar.Local;
import com.llamalad7.mixinextras.sugar.Share;
import com.llamalad7.mixinextras.sugar.ref.LocalBooleanRef;
-import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.skyblock.dungeon.StarredMobGlow;
+import de.hysky.skyblocker.skyblock.entity.MobGlow;
import net.minecraft.client.render.WorldRenderer;
import net.minecraft.entity.Entity;
@Mixin(WorldRenderer.class)
public class WorldRendererMixin {
-
@ModifyExpressionValue(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;hasOutline(Lnet/minecraft/entity/Entity;)Z"))
- private boolean skyblocker$shouldStarredMobGlow(boolean original, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) {
- boolean isAStarredMobThatShouldGlow = SkyblockerConfigManager.get().locations.dungeons.starredMobGlow && StarredMobGlow.shouldMobGlow(entity);
-
- isGlowingStarredMob.set(isAStarredMobThatShouldGlow);
-
- return original || isAStarredMobThatShouldGlow;
+ private boolean skyblocker$shouldMobGlow(boolean original, @Local Entity entity, @Share("hasCustomGlow") LocalBooleanRef hasCustomGlow) {
+ boolean shouldGlow = MobGlow.shouldMobGlow(entity);
+ hasCustomGlow.set(shouldGlow);
+ return original || shouldGlow;
}
@ModifyVariable(method = "render", at = @At("STORE"), ordinal = 0)
- private int skyblocker$modifyGlowColor(int color, @Local Entity entity, @Share("isGlowingStarredMob") LocalBooleanRef isGlowingStarredMob) {
- return isGlowingStarredMob.get() ? StarredMobGlow.getGlowColor(entity) : color;
+ private int skyblocker$modifyGlowColor(int color, @Local Entity entity, @Share("hasCustomGlow") LocalBooleanRef hasCustomGlow) {
+ return hasCustomGlow.get() ? MobGlow.getGlowColor(entity) : color;
}
}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java b/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
index d38e40cc..3c2bbc9a 100644
--- a/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
+++ b/src/main/java/de/hysky/skyblocker/mixin/YggdrasilServicesKeyInfoMixin.java
@@ -51,7 +51,7 @@ public class YggdrasilServicesKeyInfoMixin {
throw e;
}
}
-
+
@WrapOperation(method = "validateProperty", remap = false, at = @At(value = "INVOKE", target = "org/slf4j/Logger.error(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)V", remap = false))
private void skyblocker$dontLogFailedSignatureValidation(Logger logger, String message, Object property, Object exception, Operation<Void> operation) {
if (!Utils.isOnHypixel()) operation.call(logger, message, property, exception);
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java
deleted file mode 100644
index ac24c09f..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/DoubleFieldControllerMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.DoubleFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = DoubleFieldController.class, remap = false)
-public abstract class DoubleFieldControllerMixin extends NumberFieldController<Double> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
-
- public DoubleFieldControllerMixin(Option<Double> option, Function<Double, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java
deleted file mode 100644
index d67993c2..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/FloatFieldControllerMixin.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.FloatFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = FloatFieldController.class, remap = false)
-public abstract class FloatFieldControllerMixin extends NumberFieldController<Float> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
-
- public FloatFieldControllerMixin(Option<Float> option, Function<Float, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java
deleted file mode 100644
index b95cbef7..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/IntegerFieldControllerMixin.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.IntegerFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = IntegerFieldController.class, remap = false)
-public abstract class IntegerFieldControllerMixin extends NumberFieldController<Integer> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
- public IntegerFieldControllerMixin(Option<Integer> option, Function<Integer, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- return super.isInputValid(input);
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java
deleted file mode 100644
index 99871e2e..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/LongFieldControllerMixin.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.NumberFormat;
-import java.util.function.Function;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.api.Option;
-import dev.isxander.yacl3.gui.controllers.string.number.LongFieldController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import net.minecraft.text.Text;
-
-@Mixin(value = LongFieldController.class, remap = false)
-public abstract class LongFieldControllerMixin extends NumberFieldController<Long> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
-
- public LongFieldControllerMixin(Option<Long> option, Function<Long, Text> displayFormatter) {
- super(option, displayFormatter);
- }
-
- @Overwrite
- public String getString() {
- return NUMBER_FORMAT.format(option().pendingValue());
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- return super.isInputValid(input);
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java b/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java
deleted file mode 100644
index 17a99cfd..00000000
--- a/src/main/java/de/hysky/skyblocker/mixin/yacl/NumberFieldControllerMixin.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package de.hysky.skyblocker.mixin.yacl;
-
-import java.text.DecimalFormatSymbols;
-import java.text.NumberFormat;
-import java.text.ParseException;
-import java.text.ParsePosition;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-
-import dev.isxander.yacl3.gui.controllers.slider.ISliderController;
-import dev.isxander.yacl3.gui.controllers.string.number.NumberFieldController;
-import dev.isxander.yacl3.impl.utils.YACLConstants;
-import net.minecraft.util.math.MathHelper;
-
-@Mixin(value = NumberFieldController.class, remap = false)
-public abstract class NumberFieldControllerMixin<T extends Number> implements ISliderController<T> {
- private static final NumberFormat NUMBER_FORMAT = NumberFormat.getInstance();
- private static final DecimalFormatSymbols DECIMAL_FORMAT_SYMBOLS = DecimalFormatSymbols.getInstance();
-
- @Overwrite
- public void setFromString(String value) {
- try {
- setPendingValue(MathHelper.clamp(NUMBER_FORMAT.parse(value).doubleValue(), min(), max()));
- } catch (ParseException ignore) {
- YACLConstants.LOGGER.warn("Failed to parse number: {}", value);
- }
- }
-
- @Overwrite
- public boolean isInputValid(String input) {
- input = input.replace(DECIMAL_FORMAT_SYMBOLS.getGroupingSeparator() + "", "");
- ParsePosition parsePosition = new ParsePosition(0);
- NUMBER_FORMAT.parse(input, parsePosition);
-
- return parsePosition.getIndex() == input.length();
- }
-
- @Overwrite
- protected String cleanupNumberString(String number) {
- throw new UnsupportedOperationException("This method should no longer be called.");
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
index 4cd356a8..3456d1ad 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/FancyStatusBars.java
@@ -85,12 +85,11 @@ public class FancyStatusBars {
bars[bar].anchorNum = location;
// Count how many bars are in each location
- int layer1Count = 0, layer2Count = 0, rightCount = 0;
+ int layer1Count = 0, layer2Count = 0;
for (int i = 0; i < 4; i++) {
switch (bars[i].anchorNum) {
case 0 -> layer1Count++;
case 1 -> layer2Count++;
- case 2 -> rightCount++;
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
index c290e5b8..e572d9dc 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/TeleportOverlay.java
@@ -102,7 +102,7 @@ public class TeleportOverlay {
@SuppressWarnings("DataFlowIssue")
BlockState state = client.world.getBlockState(pos);
if (!state.isAir() && client.world.getBlockState(pos.up()).isAir() && client.world.getBlockState(pos.up(2)).isAir()) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ RenderHelper.renderFilled(wrc, pos, COLOR_COMPONENTS, 0.5f, false);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
index 08c22b27..5c7a01f9 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/CreeperBeams.java
@@ -31,14 +31,13 @@ public class CreeperBeams {
private static final Logger LOGGER = LoggerFactory.getLogger(CreeperBeams.class.getName());
- // "missing, this palette looks like you stole it from a 2018 bootstrap webapp!"
private static final float[][] COLORS = {
DyeColor.LIGHT_BLUE.getColorComponents(),
- DyeColor.PINK.getColorComponents(),
- DyeColor.ORANGE.getColorComponents(),
+ DyeColor.LIME.getColorComponents(),
+ DyeColor.YELLOW.getColorComponents(),
DyeColor.MAGENTA.getColorComponents(),
};
- private static final float[] LIME_COLOR_COMPONENTS = DyeColor.LIME.getColorComponents();
+ private static final float[] GREEN_COLOR_COMPONENTS = DyeColor.GREEN.getColorComponents();
private static final int FLOOR_Y = 68;
private static final int BASE_Y = 74;
@@ -81,7 +80,7 @@ public class CreeperBeams {
if (base == null) {
return;
}
- Vec3d creeperPos = new Vec3d(base.getX() + 0.5, BASE_Y + 3.5, base.getZ() + 0.5);
+ Vec3d creeperPos = new Vec3d(base.getX() + 0.5, BASE_Y + 1.75, base.getZ() + 0.5);
ArrayList<BlockPos> targets = findTargets(world, base);
beams = findLines(creeperPos, targets);
}
@@ -242,9 +241,9 @@ public class CreeperBeams {
RenderHelper.renderOutline(wrc, outlineTwo, color, 3, false);
RenderHelper.renderLinesFromPoints(wrc, line, color, 1, 2);
} else {
- RenderHelper.renderOutline(wrc, outlineOne, LIME_COLOR_COMPONENTS, 1, false);
- RenderHelper.renderOutline(wrc, outlineTwo, LIME_COLOR_COMPONENTS, 1, false);
- RenderHelper.renderLinesFromPoints(wrc, line, LIME_COLOR_COMPONENTS, 0.75f, 1);
+ RenderHelper.renderOutline(wrc, outlineOne, GREEN_COLOR_COMPONENTS, 1, false);
+ RenderHelper.renderOutline(wrc, outlineTwo, GREEN_COLOR_COMPONENTS, 1, false);
+ RenderHelper.renderLinesFromPoints(wrc, line, GREEN_COLOR_COMPONENTS, 0.75f, 1);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
index df5f36ce..02b08254 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
@@ -13,7 +13,7 @@ public class DungeonMapConfigScreen extends Screen {
private int hudX = SkyblockerConfigManager.get().locations.dungeons.mapX;
private int hudY = SkyblockerConfigManager.get().locations.dungeons.mapY;
private final Screen parent;
-
+
protected DungeonMapConfigScreen() {
this(null);
}
@@ -57,7 +57,7 @@ public class DungeonMapConfigScreen extends Screen {
SkyblockerConfigManager.get().locations.dungeons.mapX = hudX;
SkyblockerConfigManager.get().locations.dungeons.mapY = hudY;
SkyblockerConfigManager.save();
-
+
this.client.setScreen(parent);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
index 762a6e17..f40b7859 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/LividColor.java
@@ -1,18 +1,49 @@
package de.hysky.skyblocker.skyblock.dungeon;
+import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
import de.hysky.skyblocker.utils.scheduler.MessageScheduler;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
+import net.minecraft.block.Block;
+import net.minecraft.block.Blocks;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.registry.Registries;
+import net.minecraft.util.Formatting;
import net.minecraft.util.math.BlockPos;
+import java.util.Map;
+
public class LividColor {
+ private static final Map<Block, Formatting> WOOL_TO_FORMATTING = Map.of(
+ Blocks.RED_WOOL, Formatting.RED,
+ Blocks.YELLOW_WOOL, Formatting.YELLOW,
+ Blocks.LIME_WOOL, Formatting.GREEN,
+ Blocks.GREEN_WOOL, Formatting.DARK_GREEN,
+ Blocks.BLUE_WOOL, Formatting.BLUE,
+ Blocks.MAGENTA_WOOL, Formatting.LIGHT_PURPLE,
+ Blocks.PURPLE_WOOL, Formatting.DARK_PURPLE,
+ Blocks.GRAY_WOOL, Formatting.GRAY,
+ Blocks.WHITE_WOOL, Formatting.WHITE
+ );
+ private static final Map<String, Formatting> LIVID_TO_FORMATTING = Map.of(
+ "Hockey Livid", Formatting.RED,
+ "Arcade Livid", Formatting.YELLOW,
+ "Smile Livid", Formatting.GREEN,
+ "Frog Livid", Formatting.DARK_GREEN,
+ "Scream Livid", Formatting.BLUE,
+ "Crossed Livid", Formatting.LIGHT_PURPLE,
+ "Purple Livid", Formatting.DARK_PURPLE,
+ "Doctor Livid", Formatting.GRAY,
+ "Vendetta Livid", Formatting.WHITE
+ );
private static int tenTicks = 0;
+ private static Formatting color;
public static void init() {
ClientReceiveMessageEvents.GAME.register((message, overlay) -> {
- if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColor && message.getString().equals("[BOSS] Livid: I respect you for making it to here, but I'll be your undoing.")) {
+ SkyblockerConfig.LividColor config = SkyblockerConfigManager.get().locations.dungeons.lividColor;
+ if ((config.enableLividColorText || config.enableLividColorGlow) && message.getString().equals("[BOSS] Livid: I respect you for making it to here, but I'll be your undoing.")) {
tenTicks = 8;
}
});
@@ -21,16 +52,15 @@ public class LividColor {
public static void update() {
MinecraftClient client = MinecraftClient.getInstance();
if (tenTicks != 0) {
- if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColor && Utils.isInDungeons() && client.world != null) {
+ SkyblockerConfig.LividColor config = SkyblockerConfigManager.get().locations.dungeons.lividColor;
+ if ((config.enableLividColorText || config.enableLividColorGlow) && Utils.isInDungeons() && client.world != null) {
if (tenTicks == 1) {
- MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replace("[color]", "red"));
- tenTicks = 0;
+ onLividColorFound(Blocks.RED_WOOL);
return;
}
- String key = client.world.getBlockState(new BlockPos(5, 110, 42)).getBlock().getTranslationKey();
- if (key.startsWith("block.minecraft.") && key.endsWith("wool") && !key.endsWith("red_wool")) {
- MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replace("[color]", key.substring(16, key.length() - 5)));
- tenTicks = 0;
+ Block color = client.world.getBlockState(new BlockPos(5, 110, 42)).getBlock();
+ if (WOOL_TO_FORMATTING.containsKey(color) && !color.equals(Blocks.RED_WOOL)) {
+ onLividColorFound(color);
return;
}
tenTicks--;
@@ -39,4 +69,22 @@ public class LividColor {
}
}
}
+
+ private static void onLividColorFound(Block color) {
+ LividColor.color = WOOL_TO_FORMATTING.get(color);
+ if (SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColorText) {
+ String colorString = Registries.BLOCK.getId(color).getPath();
+ MessageScheduler.INSTANCE.sendMessageAfterCooldown(SkyblockerConfigManager.get().locations.dungeons.lividColor.lividColorText.replaceAll("\\[color]", colorString.substring(0, colorString.length() - 5)));
+ }
+ tenTicks = 0;
+ }
+
+ public static boolean shouldGlow(String name) {
+ return SkyblockerConfigManager.get().locations.dungeons.lividColor.enableLividColorGlow && color == LIVID_TO_FORMATTING.get(name);
+ }
+
+ @SuppressWarnings("DataFlowIssue")
+ public static int getGlowColor(String name) {
+ return LIVID_TO_FORMATTING.containsKey(name) ? LIVID_TO_FORMATTING.get(name).getColorValue() : Formatting.WHITE.getColorValue();
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java
deleted file mode 100644
index 2072017d..00000000
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/StarredMobGlow.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package de.hysky.skyblocker.skyblock.dungeon;
-
-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.predicate.entity.EntityPredicates;
-import net.minecraft.util.math.Box;
-
-import java.util.List;
-
-public class StarredMobGlow {
-
- public static boolean shouldMobGlow(Entity entity) {
- Box box = entity.getBoundingBox();
-
- if (Utils.isInDungeons() && !entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) {
- // Minibosses
- if (entity instanceof PlayerEntity) {
- switch (entity.getName().getString()) {
- case "Lost Adventurer", "Shadow Assassin", "Diamond Guy" -> {
- return true;
- }
- }
- }
-
- // Regular Mobs
- if (!(entity instanceof ArmorStandEntity)) {
- Box searchBox = box.expand(0, 2, 0);
- List<ArmorStandEntity> armorStands = entity.getWorld().getEntitiesByClass(ArmorStandEntity.class, searchBox, EntityPredicates.NOT_MOUNTED);
-
- if (!armorStands.isEmpty() && armorStands.get(0).getName().getString().contains("✯")) return true;
- }
-
- // Bats
- return entity instanceof BatEntity;
- }
-
- return false;
- }
-
- public static int getGlowColor(Entity entity) {
- if (entity instanceof PlayerEntity) {
- return switch (entity.getName().getString()) {
- case "Lost Adventurer" -> 0xfee15c;
- case "Shadow Assassin" -> 0x5b2cb2;
- case "Diamond Guy" -> 0x57c2f7;
- default -> 0xf57738;
- };
- }
-
- return 0xf57738;
- }
-}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
index 262d4a4e..53368c14 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/Trivia.java
@@ -1,7 +1,7 @@
package de.hysky.skyblocker.skyblock.dungeon;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
-import de.hysky.skyblocker.skyblock.FairySouls;
+import de.hysky.skyblocker.skyblock.waypoint.FairySouls;
import de.hysky.skyblocker.utils.chat.ChatFilterResult;
import de.hysky.skyblocker.utils.chat.ChatPatternListener;
import net.minecraft.client.MinecraftClient;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
index eda08cf6..ee517eb8 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/DungeonSecrets.java
@@ -255,7 +255,7 @@ public class DungeonSecrets {
dungeonFutures.add(CompletableFuture.runAsync(() -> {
try (BufferedReader customWaypointsReader = Files.newBufferedReader(CUSTOM_WAYPOINTS_DIR)) {
SkyblockerMod.GSON.fromJson(customWaypointsReader, JsonObject.class).asMap().forEach((room, waypointsJson) ->
- addCustomWaypoints(room, SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, waypointsJson).resultOrPartial(LOGGER::error).orElseThrow())
+ addCustomWaypoints(room, SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, waypointsJson).resultOrPartial(LOGGER::error).orElseGet(ArrayList::new))
);
LOGGER.debug("[Skyblocker Dungeon Secrets] Loaded custom dungeon secret waypoints");
} catch (Exception e) {
@@ -273,7 +273,7 @@ public class DungeonSecrets {
try (BufferedWriter writer = Files.newBufferedWriter(CUSTOM_WAYPOINTS_DIR)) {
JsonObject customWaypointsJson = new JsonObject();
customWaypoints.rowMap().forEach((room, waypoints) ->
- customWaypointsJson.add(room, SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, new ArrayList<>(waypoints.values())).resultOrPartial(LOGGER::error).orElseThrow())
+ customWaypointsJson.add(room, SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, new ArrayList<>(waypoints.values())).resultOrPartial(LOGGER::error).orElseGet(JsonArray::new))
);
SkyblockerMod.GSON.toJson(customWaypointsJson, writer);
LOGGER.info("[Skyblocker Dungeon Secrets] Saved custom dungeon secret waypoints");
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
index ecfcf496..9b95f146 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/Room.java
@@ -41,6 +41,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Room {
+ private static final Pattern SECRET_INDEX = Pattern.compile("^(\\d+)");
private static final Pattern SECRETS = Pattern.compile("§7(\\d{1,2})/(\\d{1,2}) Secrets");
@NotNull
private final Type type;
@@ -70,11 +71,12 @@ public class Room {
private int doubleCheckBlocks;
/**
* Represents the matching state of the room with the following possible values:
- * <li>{@link TriState#DEFAULT} means that the room has not been checked, is being processed, or does not {@link Type#needsScanning() need to be processed}.
- * <li>{@link TriState#FALSE} means that the room has been checked and there is no match.
- * <li>{@link TriState#TRUE} means that the room has been checked and there is a match.
+ * <li>{@link MatchState#MATCHING} means that the room has not been checked, is being processed, or does not {@link Type#needsScanning() need to be processed}.</li>
+ * <li>{@link MatchState#DOUBLE_CHECKING} means that the room has a unique match and is being double checked.</li>
+ * <li>{@link MatchState#MATCHED} means that the room has a unique match ans has been double checked.</li>
+ * <li>{@link MatchState#FAILED} means that the room has been checked and there is no match.</li>
*/
- private TriState matched = TriState.DEFAULT;
+ private MatchState matchState = MatchState.MATCHING;
private Table<Integer, BlockPos, SecretWaypoint> secretWaypoints;
private String name;
private Direction direction;
@@ -96,7 +98,7 @@ public class Room {
}
public boolean isMatched() {
- return matched == TriState.TRUE;
+ return matchState == MatchState.DOUBLE_CHECKING || matchState == MatchState.MATCHED;
}
/**
@@ -108,7 +110,7 @@ public class Room {
@Override
public String toString() {
- return "Room{type=" + type + ", shape=" + shape + ", matched=" + matched + ", segments=" + Arrays.toString(segments.toArray()) + "}";
+ return "Room{type=%s, segments=%s, shape=%s, matchState=%s, name=%s, direction=%s, physicalCornerPos=%s}".formatted(type, Arrays.toString(segments.toArray()), shape, matchState, name, direction, physicalCornerPos);
}
@NotNull
@@ -208,6 +210,7 @@ public class Room {
/**
* Removes a custom waypoint relative to this room from {@link DungeonSecrets#customWaypoints} and all existing instances of this room.
+ *
* @param pos the position of the secret waypoint relative to this room
* @return the removed secret waypoint or {@code null} if there was no secret waypoint at the given position
*/
@@ -223,6 +226,7 @@ public class Room {
/**
* Removes a custom waypoint relative to this room from this instance of the room.
+ *
* @param secretIndex the index of the secret waypoint
* @param relativePos the position of the secret waypoint relative to this room
*/
@@ -237,7 +241,7 @@ public class Room {
* This method returns immediately if any of the following conditions are met:
* <ul>
* <li> The room does not need to be scanned and matched. (When the room is not of type {@link Type.ROOM}, {@link Type.PUZZLE}, or {@link Type.TRAP}. See {@link Type#needsScanning()}) </li>
- * <li> The room has been matched or failed to match and is on cooldown. See {@link #matched}. </li>
+ * <li> The room has been matched or failed to match and is on cooldown. See {@link #matchState}. </li>
* <li> {@link #findRoom The previous update} has not completed. </li>
* </ul>
* Then this method tries to match this room through:
@@ -251,7 +255,7 @@ public class Room {
@SuppressWarnings("JavadocReference")
protected void update() {
// Logical AND has higher precedence than logical OR
- if (!type.needsScanning() || matched != TriState.DEFAULT || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) {
+ if (!type.needsScanning() || matchState != MatchState.MATCHING && matchState != MatchState.DOUBLE_CHECKING || !DungeonSecrets.isRoomsLoaded() || findRoom != null && !findRoom.isDone()) {
return;
}
MinecraftClient client = MinecraftClient.getInstance();
@@ -266,6 +270,9 @@ public class Room {
break;
}
}
+ }).exceptionally(e -> {
+ DungeonSecrets.LOGGER.error("[Skyblocker Dungeon Secrets] Encountered an unknown exception while matching room {}", this, e);
+ return null;
});
}
@@ -297,16 +304,24 @@ public class Room {
* </ul>
* <li> If there are no matching rooms left: </li>
* <ul>
- * <li> Terminate matching by setting {@link #matched} to {@link TriState#FALSE}. </li>
+ * <li> Terminate matching by setting {@link #matchState} to {@link TriState#FALSE}. </li>
* <li> Schedule another matching attempt in 50 ticks (2.5 seconds). </li>
* <li> Reset {@link #possibleRooms} and {@link #checkedBlocks} with {@link #reset()}. </li>
* <li> Return {@code true} </li>
* </ul>
* <li> If there are exactly one room matching: </li>
* <ul>
- * <li> Call {@link #roomMatched()}. </li>
- * <li> Discard the no longer needed fields to save memory. </li>
- * <li> Return {@code true} </li>
+ * <li> If {@link #matchState} is {@link MatchState#MATCHING}: </li>
+ * <ul>
+ * <li> Call {@link #roomMatched()}. </li>
+ * <li> Return {@code false}. </li>
+ * </ul>
+ * <li> If {@link #matchState} is {@link MatchState#DOUBLE_CHECKING}: </li>
+ * <ul>
+ * <li> Set the match state to {@link MatchState#MATCHED}. </li>
+ * <li> Discard the no longer needed fields to save memory. </li>
+ * <li> Return {@code true}. </li>
+ * </ul>
* </ul>
* <li> Return {@code false} </li>
* </ul>
@@ -334,26 +349,29 @@ public class Room {
int matchingRoomsSize = possibleRooms.stream().map(Triple::getRight).mapToInt(Collection::size).sum();
if (matchingRoomsSize == 0) {
// If no rooms match, reset the fields and scan again after 50 ticks.
- matched = TriState.FALSE;
- DungeonSecrets.LOGGER.warn("[Skyblocker] No dungeon room matches after checking {} block(s)", checkedBlocks.size());
- Scheduler.INSTANCE.schedule(() -> matched = TriState.DEFAULT, 50);
+ DungeonSecrets.LOGGER.warn("[Skyblocker Dungeon Secrets] No dungeon room matched after checking {} block(s) including double checking {} block(s)", checkedBlocks.size(), doubleCheckBlocks);
+ Scheduler.INSTANCE.schedule(() -> matchState = MatchState.MATCHING, 50);
reset();
return true;
- } else if (matchingRoomsSize == 1 && ++doubleCheckBlocks >= 10) {
- // If one room matches, load the secrets for that room and discard the no longer needed fields.
- for (Triple<Direction, Vector2ic, List<String>> directionRooms : possibleRooms) {
- if (directionRooms.getRight().size() == 1) {
- name = directionRooms.getRight().get(0);
- direction = directionRooms.getLeft();
- physicalCornerPos = directionRooms.getMiddle();
- roomMatched();
- discard();
- return true;
- }
+ } else if (matchingRoomsSize == 1) {
+ if (matchState == MatchState.MATCHING) {
+ // If one room matches, load the secrets for that room and set state to double-checking.
+ Triple<Direction, Vector2ic, List<String>> directionRoom = possibleRooms.stream().filter(directionRooms -> directionRooms.getRight().size() == 1).findAny().orElseThrow();
+ name = directionRoom.getRight().get(0);
+ direction = directionRoom.getLeft();
+ physicalCornerPos = directionRoom.getMiddle();
+ DungeonSecrets.LOGGER.info("[Skyblocker Dungeon Secrets] Room {} matched after checking {} block(s), starting double checking", name, checkedBlocks.size());
+ roomMatched();
+ return false;
+ } else if (matchState == MatchState.DOUBLE_CHECKING && ++doubleCheckBlocks >= 10) {
+ // If double-checked, set state to matched and discard the no longer needed fields.
+ DungeonSecrets.LOGGER.info("[Skyblocker Dungeon Secrets] Room {} matched after checking {} block(s) including double checking {} block(s)", name, checkedBlocks.size(), doubleCheckBlocks);
+ discard();
+ return true;
}
- return false; // This should never happen, we just checked that there is one possible room, and the return true in the loop should activate
+ return false;
} else {
- DungeonSecrets.LOGGER.debug("[Skyblocker] {} room(s) remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size());
+ DungeonSecrets.LOGGER.debug("[Skyblocker Dungeon Secrets] {} room(s) remaining after checking {} block(s)", matchingRoomsSize, checkedBlocks.size());
return false;
}
}
@@ -371,7 +389,7 @@ public class Room {
/**
* Loads the secret waypoints for the room from {@link DungeonSecrets#waypointsJson} once it has been matched
- * and sets {@link #matched} to {@link TriState#TRUE}.
+ * and sets {@link #matchState} to {@link MatchState#DOUBLE_CHECKING}.
*
* @param directionRooms the direction, position, and name of the room
*/
@@ -381,25 +399,29 @@ public class Room {
for (JsonElement waypointElement : DungeonSecrets.getRoomWaypoints(name)) {
JsonObject waypoint = waypointElement.getAsJsonObject();
String secretName = waypoint.get("secretName").getAsString();
- int secretIndex = Integer.parseInt(secretName.substring(0, Character.isDigit(secretName.charAt(1)) ? 2 : 1));
+ Matcher secretIndexMatcher = SECRET_INDEX.matcher(secretName);
+ int secretIndex = secretIndexMatcher.find() ? Integer.parseInt(secretIndexMatcher.group(1)) : 0;
BlockPos pos = DungeonMapUtils.relativeToActual(direction, physicalCornerPos, waypoint);
secretWaypoints.put(secretIndex, pos, new SecretWaypoint(secretIndex, waypoint, secretName, pos));
}
DungeonSecrets.getCustomWaypoints(name).values().forEach(this::addCustomWaypoint);
- matched = TriState.TRUE;
-
- DungeonSecrets.LOGGER.info("[Skyblocker] Room {} matched after checking {} block(s)", name, checkedBlocks.size());
+ matchState = MatchState.DOUBLE_CHECKING;
}
/**
* Resets fields for another round of matching after room matching fails.
*/
private void reset() {
+ matchState = MatchState.FAILED;
IntSortedSet segmentsX = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::x).toArray()));
IntSortedSet segmentsY = IntSortedSets.unmodifiable(new IntRBTreeSet(segments.stream().mapToInt(Vector2ic::y).toArray()));
possibleRooms = getPossibleRooms(segmentsX, segmentsY);
checkedBlocks = new HashSet<>();
doubleCheckBlocks = 0;
+ secretWaypoints = null;
+ name = null;
+ direction = null;
+ physicalCornerPos = null;
}
/**
@@ -407,6 +429,7 @@ public class Room {
* These fields are no longer needed and are discarded to save memory.
*/
private void discard() {
+ matchState = MatchState.MATCHED;
roomsData = null;
possibleRooms = null;
checkedBlocks = null;
@@ -473,7 +496,7 @@ public class Room {
BlockState state = world.getBlockState(hitResult.getBlockPos());
if (state.isOf(Blocks.CHEST) || state.isOf(Blocks.PLAYER_HEAD) || state.isOf(Blocks.PLAYER_WALL_HEAD)) {
secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::needsInteraction).findAny()
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} interaction, setting secret #{} as found", secretWaypoint.category, secretWaypoint.secretIndex));
} else if (state.isOf(Blocks.LEVER)) {
secretWaypoints.column(hitResult.getBlockPos()).values().stream().filter(SecretWaypoint::isLever).forEach(SecretWaypoint::setFound);
}
@@ -491,7 +514,7 @@ public class Room {
return;
}
secretWaypoints.values().stream().filter(SecretWaypoint::needsItemPickup).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(collector))).filter(SecretWaypoint.getRangePredicate(collector))
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} picked up a {} from a {} secret, setting secret #{} as found", collector.getName().getString(), itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} picked up a {} from a {} secret, setting secret #{} as found", collector.getName().getString(), itemEntity.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
}
/**
@@ -502,7 +525,7 @@ public class Room {
*/
protected void onBatRemoved(AmbientEntity bat) {
secretWaypoints.values().stream().filter(SecretWaypoint::isBat).min(Comparator.comparingDouble(SecretWaypoint.getSquaredDistanceToFunction(bat)))
- .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
+ .ifPresent(secretWaypoint -> onSecretFound(secretWaypoint, "[Skyblocker Dungeon Secrets] Detected {} killed for a {} secret, setting secret #{} as found", bat.getName().getString(), secretWaypoint.category, secretWaypoint.secretIndex));
}
/**
@@ -575,4 +598,8 @@ public class Room {
public enum Direction {
NW, NE, SW, SE
}
+
+ public enum MatchState {
+ MATCHING, DOUBLE_CHECKING, MATCHED, FAILED
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
index 0c2d1b34..43f624f6 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypoint.java
@@ -20,6 +20,8 @@ import net.minecraft.util.dynamic.Codecs;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import org.jetbrains.annotations.NotNull;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.List;
import java.util.function.Predicate;
@@ -27,6 +29,7 @@ import java.util.function.Supplier;
import java.util.function.ToDoubleFunction;
public class SecretWaypoint extends Waypoint {
+ protected static final Logger LOGGER = LoggerFactory.getLogger(SecretWaypoint.class);
public static final Codec<SecretWaypoint> CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.INT.fieldOf("secretIndex").forGetter(secretWaypoint -> secretWaypoint.secretIndex),
Category.CODEC.fieldOf("category").forGetter(secretWaypoint -> secretWaypoint.category),
@@ -35,8 +38,8 @@ public class SecretWaypoint extends Waypoint {
).apply(instance, SecretWaypoint::new));
public static final Codec<List<SecretWaypoint>> LIST_CODEC = CODEC.listOf();
static final List<String> SECRET_ITEMS = List.of("Decoy", "Defuse Kit", "Dungeon Chest Key", "Healing VIII", "Inflatable Jerry", "Spirit Leap", "Training Weights", "Trap", "Treasure Talisman");
- private static final SkyblockerConfig.SecretWaypoints CONFIG = SkyblockerConfigManager.get().locations.dungeons.secretWaypoints;
- private static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.waypointType;
+ private static final Supplier<SkyblockerConfig.SecretWaypoints> CONFIG = () -> SkyblockerConfigManager.get().locations.dungeons.secretWaypoints;
+ private static final Supplier<Type> TYPE_SUPPLIER = () -> CONFIG.get().waypointType;
final int secretIndex;
final Category category;
final Text name;
@@ -95,7 +98,7 @@ public class SecretWaypoint extends Waypoint {
//TODO In the future, shrink the box for wither essence and items so its more realistic
super.render(context);
- if (CONFIG.showSecretText) {
+ if (CONFIG.get().showSecretText) {
Vec3d posUp = centerPos.add(0, 1, 0);
RenderHelper.renderText(context, name, posUp, true);
double distance = context.camera().getPos().distanceTo(centerPos);
@@ -135,8 +138,8 @@ public class SecretWaypoint extends Waypoint {
}
}
- private static Category get(JsonObject waypointJson) {
- return CODEC.parse(JsonOps.INSTANCE, waypointJson.get("category")).resultOrPartial(DungeonSecrets.LOGGER::error).orElseThrow();
+ static Category get(JsonObject waypointJson) {
+ return CODEC.parse(JsonOps.INSTANCE, waypointJson.get("category")).resultOrPartial(LOGGER::error).orElse(Category.DEFAULT);
}
boolean needsInteraction() {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
index 9bd6bef1..6f281ba9 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
@@ -23,7 +23,7 @@ public class DwarvenHudConfigScreen extends Screen {
protected DwarvenHudConfigScreen() {
this(null);
}
-
+
public DwarvenHudConfigScreen(Screen parent) {
super(Text.of("Dwarven HUD Config"));
this.parent = parent;
@@ -62,7 +62,7 @@ public class DwarvenHudConfigScreen extends Screen {
SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.x = hudX;
SkyblockerConfigManager.get().locations.dwarvenMines.dwarvenHud.y = hudY;
SkyblockerConfigManager.save();
-
+
client.setScreen(parent);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
new file mode 100644
index 00000000..5e0995e6
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/entity/MobGlow.java
@@ -0,0 +1,83 @@
+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.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.predicate.entity.EntityPredicates;
+import net.minecraft.util.Formatting;
+import net.minecraft.util.math.Box;
+import net.minecraft.world.World;
+
+public class MobGlow {
+ public static boolean shouldMobGlow(Entity entity) {
+ Box box = entity.getBoundingBox();
+
+ if (!entity.isInvisible() && OcclusionCulling.isVisible(box.minX, box.minY, box.minZ, box.maxX, box.maxY, box.maxZ)) {
+ String name = entity.getName().getString();
+
+ // 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);
+ }
+ }
+
+ // 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;
+ }
+
+ // 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;
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static List<ArmorStandEntity> getArmorStands(World world, Box box) {
+ return world.getEntitiesByClass(ArmorStandEntity.class, box.expand(0, 2, 0), EntityPredicates.NOT_MOUNTED);
+ }
+
+ public static int getGlowColor(Entity entity) {
+ String name = entity.getName().getString();
+
+ if (entity instanceof PlayerEntity) {
+ return switch (name) {
+ case "Lost Adventurer" -> 0xfee15c;
+ 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);
+ case "Blobbercyst " -> Formatting.GREEN.getColorValue();
+ default -> 0xf57738;
+ };
+ }
+
+ return 0xf57738;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java b/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
index 5fd6f741..d6a40d2d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/filters/ComboFilter.java
@@ -5,8 +5,8 @@ import de.hysky.skyblocker.utils.chat.ChatFilterResult;
public class ComboFilter extends SimpleChatFilter {
public ComboFilter() {
- super("^(\\+\\d+ Kill Combo \\+\\d+(% ✯ Magic Find| coins per kill|% Combat Exp)" +
- "|Your Kill Combo has expired! You reached a \\d+ Kill Combo!)$");
+ // ^(\+\d+ Kill Combo( \+\d+(✯ Magic Find| coins per kill|☯ Combat Wisdom))?|Your Kill Combo has expired! You reached a \d+ Kill Combo!)$
+ super("^(\\+\\d+ Kill Combo( \\+\\d+(✯ Magic Find| coins per kill|☯ Combat Wisdom))?|Your Kill Combo has expired! You reached a \\d+ Kill Combo!)$");
}
@Override
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java b/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
index cec84b38..3434f026 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/CustomArmorTrims.java
@@ -145,7 +145,7 @@ public class CustomArmorTrims {
Identifier.CODEC.fieldOf("material").forGetter(ArmorTrimId::material),
Identifier.CODEC.fieldOf("pattern").forGetter(ArmorTrimId::pattern))
.apply(instance, ArmorTrimId::new));
-
+
@Override
public Identifier left() {
return material();
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
index 9e1df2bb..8867af91 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/ItemRarityBackgrounds.java
@@ -1,8 +1,14 @@
package de.hysky.skyblocker.skyblock.item;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Supplier;
+
import com.google.common.collect.ImmutableMap;
import com.mojang.blaze3d.systems.RenderSystem;
-import de.hysky.skyblocker.SkyblockerMod;
+
+import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
@@ -16,16 +22,10 @@ import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.texture.Sprite;
import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
-import net.minecraft.util.Identifier;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.function.Supplier;
public class ItemRarityBackgrounds {
- private static final Identifier RARITY_BG_TEX = new Identifier(SkyblockerMod.NAMESPACE, "item_rarity_background");
- private static final Supplier<Sprite> SPRITE = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(RARITY_BG_TEX);
+ private static final SkyblockerConfig.ItemInfoDisplay CONFIG = SkyblockerConfigManager.get().general.itemInfoDisplay;
+ private static final Supplier<Sprite> SPRITE = () -> MinecraftClient.getInstance().getGuiAtlasManager().getSprite(CONFIG.itemRarityBackgroundStyle.tex);
private static final ImmutableMap<String, SkyblockItemRarity> LORE_RARITIES = ImmutableMap.ofEntries(
Map.entry("ADMIN", SkyblockItemRarity.ADMIN),
Map.entry("SPECIAL", SkyblockItemRarity.SPECIAL), //Very special is the same color so this will cover it
@@ -39,27 +39,27 @@ public class ItemRarityBackgrounds {
Map.entry("COMMON", SkyblockItemRarity.COMMON)
);
private static final Int2ReferenceOpenHashMap<SkyblockItemRarity> CACHE = new Int2ReferenceOpenHashMap<>();
-
+
public static void init() {
//Clear the cache every 5 minutes, ints are very compact!
Scheduler.INSTANCE.scheduleCyclic(CACHE::clear, 4800);
-
+
//Clear cache after a screen where items can be upgraded in rarity closes
ScreenEvents.BEFORE_INIT.register((client, screen, scaledWidth, scaledHeight) -> {
String title = screen.getTitle().getString();
-
+
if (Utils.isOnSkyblock() && (title.equals("The Hex") || title.equals("Craft Item") || title.equals("Anvil") || title.equals("Reforge Anvil"))) {
ScreenEvents.remove(screen).register(screen1 -> CACHE.clear());
}
});
}
-
+
public static void tryDraw(ItemStack stack, DrawContext context, int x, int y) {
MinecraftClient client = MinecraftClient.getInstance();
-
+
if (client.player != null) {
SkyblockItemRarity itemRarity = getItemRarity(stack, client.player);
-
+
if (itemRarity != null) draw(context, x, y, itemRarity);
}
}
@@ -73,30 +73,30 @@ public class ItemRarityBackgrounds {
int hashCode = itemUuid.isEmpty() ? System.identityHashCode(stack) : itemUuid.hashCode();
if (CACHE.containsKey(hashCode)) return CACHE.get(hashCode);
-
+
List<Text> tooltip = stack.getTooltip(player, TooltipContext.BASIC);
String[] stringifiedTooltip = tooltip.stream().map(Text::getString).toArray(String[]::new);
-
+
for (String rarityString : LORE_RARITIES.keySet()) {
if (Arrays.stream(stringifiedTooltip).anyMatch(line -> line.contains(rarityString))) {
SkyblockItemRarity rarity = LORE_RARITIES.get(rarityString);
-
+
CACHE.put(hashCode, rarity);
return rarity;
}
}
-
+
CACHE.put(hashCode, null);
return null;
}
-
+
private static void draw(DrawContext context, int x, int y, SkyblockItemRarity rarity) {
//Enable blending to handle HUD translucency
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
context.drawSprite(x, y, 0, 16, 16, SPRITE.get(), rarity.r, rarity.g, rarity.b, SkyblockerConfigManager.get().general.itemInfoDisplay.itemRarityBackgroundsOpacity);
-
+
RenderSystem.disableBlend();
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java b/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
index ac9b1bf0..823c4c99 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/MuseumItemCache.java
@@ -40,18 +40,19 @@ public class MuseumItemCache {
private static final Path CACHE_FILE = SkyblockerMod.CONFIG_DIR.resolve("museum_item_cache.json");
private static final Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>> MUSEUM_ITEM_CACHE = new Object2ObjectOpenHashMap<>();
private static final Type MAP_TYPE = new TypeToken<Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>>>() {}.getType();
-
+ private static final String ERROR_LOG_TEMPLATE = "[Skyblocker] Failed to refresh museum item data for profile {}";
+
private static CompletableFuture<Void> loaded;
public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(MuseumItemCache::load);
}
-
+
private static void load(MinecraftClient client) {
loaded = CompletableFuture.runAsync(() -> {
try (BufferedReader reader = Files.newBufferedReader(CACHE_FILE)) {
Object2ObjectOpenHashMap<String, Object2ObjectOpenHashMap<String, ProfileMuseumData>> cachedData = SkyblockerMod.GSON.fromJson(reader, MAP_TYPE);
-
+
MUSEUM_ITEM_CACHE.putAll(cachedData);
LOGGER.info("[Skyblocker] Loaded museum items cache");
} catch (NoSuchFileException ignored) {
@@ -60,7 +61,7 @@ public class MuseumItemCache {
}
});
}
-
+
private static void save() {
CompletableFuture.runAsync(() -> {
try (BufferedWriter writer = Files.newBufferedWriter(CACHE_FILE)) {
@@ -70,48 +71,70 @@ public class MuseumItemCache {
}
});
}
-
+
private static void updateData4ProfileMember(String uuid, String profileId) {
CompletableFuture.runAsync(() -> {
try (ApiResponse response = Http.sendHypixelRequest("skyblock/museum", "?profile=" + profileId)) {
//The request was successful
if (response.ok()) {
JsonObject profileData = JsonParser.parseString(response.content()).getAsJsonObject();
- JsonObject memberData = profileData.get("members").getAsJsonObject().get(uuid).getAsJsonObject();
-
- //We call them sets because it could either be a singular item or an entire armour set
- Map<String, JsonElement> donatedSets = memberData.get("items").getAsJsonObject().asMap();
-
- //Set of all found item ids on profile
- ObjectOpenHashSet<String> itemIds = new ObjectOpenHashSet<>();
-
- for (Map.Entry<String, JsonElement> donatedSet : donatedSets.entrySet()) {
- //Item is plural here because the nbt is a list
- String itemsData = donatedSet.getValue().getAsJsonObject().get("items").getAsJsonObject().get("data").getAsString();
- NbtList items = NbtIo.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(itemsData))).getList("i", NbtElement.COMPOUND_TYPE);
-
- for (int i = 0; i < items.size(); i++) {
- NbtCompound tag = items.getCompound(i).getCompound("tag");
-
- if (tag.contains("ExtraAttributes")) {
- NbtCompound extraAttributes = tag.getCompound("ExtraAttributes");
-
- if (extraAttributes.contains("id")) itemIds.add(extraAttributes.getString("id"));
+ JsonObject members = profileData.getAsJsonObject("members");
+
+ if (members.has(uuid)) {
+ JsonObject memberData = members.get(uuid).getAsJsonObject();
+
+ //We call them sets because it could either be a singular item or an entire armour set
+ Map<String, JsonElement> donatedSets = memberData.get("items").getAsJsonObject().asMap();
+
+ //Set of all found item ids on profile
+ ObjectOpenHashSet<String> itemIds = new ObjectOpenHashSet<>();
+
+ for (Map.Entry<String, JsonElement> donatedSet : donatedSets.entrySet()) {
+ //Item is plural here because the nbt is a list
+ String itemsData = donatedSet.getValue().getAsJsonObject().get("items").getAsJsonObject().get("data").getAsString();
+ NbtList items = NbtIo.readCompressed(new ByteArrayInputStream(Base64.getDecoder().decode(itemsData))).getList("i", NbtElement.COMPOUND_TYPE);
+
+ for (int i = 0; i < items.size(); i++) {
+ NbtCompound tag = items.getCompound(i).getCompound("tag");
+
+ if (tag.contains("ExtraAttributes")) {
+ NbtCompound extraAttributes = tag.getCompound("ExtraAttributes");
+
+ if (extraAttributes.contains("id")) itemIds.add(extraAttributes.getString("id"));
+ }
}
}
+
+ MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), itemIds));
+ save();
+
+ LOGGER.info("[Skyblocker] Successfully updated museum item cache for profile {}", profileId);
+ } else {
+ //If the player's Museum API is disabled
+ putEmpty(uuid, profileId);
+
+ LOGGER.warn(ERROR_LOG_TEMPLATE + " because the Museum API is disabled!", profileId);
}
-
- MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), itemIds));
- save();
-
- LOGGER.info("[Skyblocker] Successfully updated museum item cache for profile {}", profileId);
+ } else {
+ //If the request returns a non 200 status code
+ putEmpty(uuid, profileId);
+
+ LOGGER.error(ERROR_LOG_TEMPLATE + " because a non 200 status code was encountered! Status Code: {}", profileId, response.statusCode());
}
} catch (Exception e) {
- LOGGER.error("[Skyblocker] Failed to refresh museum item data for profile {}", profileId, e);
+ //If an exception was somehow thrown
+ putEmpty(uuid, profileId);
+
+ LOGGER.error(ERROR_LOG_TEMPLATE, profileId, e);
}
});
}
-
+
+ private static void putEmpty(String uuid, String profileId) {
+ MUSEUM_ITEM_CACHE.get(uuid).put(profileId, new ProfileMuseumData(System.currentTimeMillis(), ObjectOpenHashSet.of()));
+ save();
+ }
+
/**
* The cache is ticked upon switching skyblock servers
*/
@@ -121,22 +144,22 @@ public class MuseumItemCache {
Object2ObjectOpenHashMap<String, ProfileMuseumData> playerData = MUSEUM_ITEM_CACHE.computeIfAbsent(uuid, uuid1 -> Util.make(new Object2ObjectOpenHashMap<>(), map -> {
map.put(profileId, ProfileMuseumData.EMPTY);
}));
-
+
if (playerData.get(profileId).stale()) updateData4ProfileMember(uuid, profileId);
}
}
-
+
public static boolean hasItemInMuseum(String id) {
String uuid = UndashedUuid.toString(MinecraftClient.getInstance().getSession().getUuidOrNull());
- ObjectOpenHashSet<String> collectedItemIds = MUSEUM_ITEM_CACHE.get(uuid).get(Utils.getProfileId()).collectedItemIds();
-
+ ObjectOpenHashSet<String> collectedItemIds = (!MUSEUM_ITEM_CACHE.containsKey(uuid) || Utils.getProfileId().isBlank() || !MUSEUM_ITEM_CACHE.get(uuid).containsKey(Utils.getProfileId())) ? null : MUSEUM_ITEM_CACHE.get(uuid).get(Utils.getProfileId()).collectedItemIds();
+
return collectedItemIds != null && collectedItemIds.contains(id);
}
-
+
private record ProfileMuseumData(long lastUpdated, ObjectOpenHashSet<String> collectedItemIds) {
private static final ProfileMuseumData EMPTY = new ProfileMuseumData(0L, null);
private static final long MAX_AGE = 86_400_000;
-
+
private boolean stale() {
return System.currentTimeMillis() > lastUpdated + MAX_AGE;
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
index 08cc5377..07a566af 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/SkyblockItemRarity.java
@@ -13,7 +13,7 @@ public enum SkyblockItemRarity {
RARE(Formatting.BLUE),
UNCOMMON(Formatting.GREEN),
COMMON(Formatting.WHITE);
-
+
public final float r;
public final float g;
public final float b;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
index e050aff5..adc23bbb 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/ItemTooltip.java
@@ -4,6 +4,7 @@ import com.google.gson.JsonObject;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
+import de.hysky.skyblocker.skyblock.item.MuseumItemCache;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.ItemUtils;
import de.hysky.skyblocker.utils.Utils;
@@ -146,26 +147,41 @@ public class ItemTooltip {
.append(getMotesMessage(TooltipInfoType.MOTES.getData().get(internalID).getAsInt(), count)));
}
- if (TooltipInfoType.MUSEUM.isTooltipEnabled() && !bazaarOpened) {
+ if (TooltipInfoType.OBTAINED.isTooltipEnabled()) {
String timestamp = getTimestamp(stack);
- if (TooltipInfoType.MUSEUM.hasOrNullWarning(internalID)) {
- String itemCategory = TooltipInfoType.MUSEUM.getData().get(internalID).getAsString();
- String format = switch (itemCategory) {
- case "Weapons" -> "%-18s";
- case "Armor" -> "%-19s";
- default -> "%-20s";
- };
- lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")"))
- .formatted(Formatting.LIGHT_PURPLE)
- .append(Text.literal(timestamp).formatted(Formatting.RED)));
- } else if (!timestamp.isEmpty()) {
+ if (!timestamp.isEmpty()) {
lines.add(Text.literal(String.format("%-21s", "Obtained: "))
.formatted(Formatting.LIGHT_PURPLE)
.append(Text.literal(timestamp).formatted(Formatting.RED)));
}
}
+ if (TooltipInfoType.MUSEUM.isTooltipEnabledAndHasOrNullWarning(internalID) && !bazaarOpened) {
+ String itemCategory = TooltipInfoType.MUSEUM.getData().get(internalID).getAsString();
+ String format = switch (itemCategory) {
+ case "Weapons" -> "%-18s";
+ case "Armor" -> "%-19s";
+ default -> "%-20s";
+ };
+
+ //Special case the special category so that it doesn't always display not donated
+ if (itemCategory.equals("Special")) {
+ lines.add(Text.literal(String.format(format, "Museum: (" + itemCategory + ")"))
+ .formatted(Formatting.LIGHT_PURPLE));
+ } else {
+ NbtCompound extraAttributes = ItemUtils.getExtraAttributes(stack);
+ boolean isInMuseum = (extraAttributes.contains("donated_museum") && extraAttributes.getBoolean("donated_museum")) || MuseumItemCache.hasItemInMuseum(internalID);
+
+ Formatting donatedIndicatorFormatting = isInMuseum ? Formatting.GREEN : Formatting.RED;
+
+ lines.add(Text.literal(String.format(format, "Museum (" + itemCategory + "):"))
+ .formatted(Formatting.LIGHT_PURPLE)
+ .append(Text.literal(isInMuseum ? "✔" : "✖").formatted(donatedIndicatorFormatting, Formatting.BOLD))
+ .append(Text.literal(isInMuseum ? " Donated" : " Not Donated").formatted(donatedIndicatorFormatting)));
+ }
+ }
+
if (TooltipInfoType.COLOR.isTooltipEnabledAndHasOrNullWarning(internalID) && stack.getNbt() != null) {
final NbtElement color = stack.getNbt().getCompound("display").get("color");
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
index 086fcb00..38dcb762 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/item/tooltip/TooltipInfoType.java
@@ -20,7 +20,8 @@ public enum TooltipInfoType implements Runnable {
ONE_DAY_AVERAGE("https://moulberry.codes/auction_averages_lbin/1day.json", itemTooltip -> itemTooltip.enableAvgBIN, false),
THREE_DAY_AVERAGE("https://moulberry.codes/auction_averages_lbin/3day.json", itemTooltip -> itemTooltip.enableAvgBIN, false),
MOTES("https://hysky.de/api/motesprice", itemTooltip -> itemTooltip.enableMotesPrice, itemTooltip -> itemTooltip.enableMotesPrice && Utils.isInTheRift(), true),
- MUSEUM("https://hysky.de/api/museum", itemTooltip -> itemTooltip.enableMuseumDate, true),
+ OBTAINED(itemTooltip -> itemTooltip.enableObtainedDate),
+ MUSEUM("https://hysky.de/api/museum", itemTooltip -> itemTooltip.enableMuseumInfo, true),
COLOR("https://hysky.de/api/color", itemTooltip -> itemTooltip.enableExoticTooltip, true);
private final String address;
@@ -31,6 +32,13 @@ public enum TooltipInfoType implements Runnable {
private long hash;
/**
+ * Use this for when you're adding tooltip info that has no data associated with it
+ */
+ TooltipInfoType(Predicate<SkyblockerConfig.ItemTooltip> enabled) {
+ this(null, itemTooltip -> false, enabled, null, false);
+ }
+
+ /**
* @param address the address to download the data from
* @param enabled the predicate to check if the data should be downloaded and the tooltip should be shown
* @param cacheable whether the data should be cached
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
index a0e1a0f2..95e08c80 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EffigyWaypoints.java
@@ -30,15 +30,15 @@ public class EffigyWaypoints {
if (!SkyblockerConfigManager.get().slayer.vampireSlayer.enableEffigyWaypoints || !Utils.isOnSkyblock() || !Utils.isInTheRift() || !Utils.getIslandArea().contains("Stillgore Château")) return;
UNBROKEN_EFFIGIES.clear();
-
+
try {
for (int i = 0; i < Utils.STRING_SCOREBOARD.size(); i++) {
String line = Utils.STRING_SCOREBOARD.get(i);
-
+
if (line.contains("Effigies")) {
List<Text> effigiesText = new ArrayList<>();
List<Text> prefixAndSuffix = Utils.TEXT_SCOREBOARD.get(i).getSiblings();
-
+
//Add contents of prefix and suffix to list
effigiesText.addAll(prefixAndSuffix.get(0).getSiblings());
effigiesText.addAll(prefixAndSuffix.get(1).getSiblings());
@@ -58,11 +58,11 @@ public class EffigyWaypoints {
for (BlockPos effigy : UNBROKEN_EFFIGIES) {
float[] colorComponents = DyeColor.RED.getColorComponents();
if (SkyblockerConfigManager.get().slayer.vampireSlayer.compactEffigyWaypoints) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F);
+ RenderHelper.renderFilledWithBeaconBeam(context, effigy.down(6), colorComponents, 0.5F, true);
} else {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, effigy, colorComponents, 0.5F);
+ RenderHelper.renderFilledWithBeaconBeam(context, effigy, colorComponents, 0.5F, true);
for (int i = 1; i < 6; i++) {
- RenderHelper.renderFilledThroughWalls(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i));
+ RenderHelper.renderFilled(context, effigy.down(i), colorComponents, 0.5F - (0.075F * i), true);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
index 744edd4c..aa55a4e3 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/EnigmaSouls.java
@@ -1,38 +1,19 @@
package de.hysky.skyblocker.skyblock.rift;
-import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
-
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfig;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
-import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
-import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
@@ -43,13 +24,27 @@ import net.minecraft.util.DyeColor;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
+import java.util.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class EnigmaSouls {
private static final Logger LOGGER = LoggerFactory.getLogger(EnigmaSouls.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/enigma_soul_waypoints.json");
- private static final BlockPos[] SOUL_WAYPOINTS = new BlockPos[42];
+ private static final Map<BlockPos, ProfileAwareWaypoint> SOUL_WAYPOINTS = new HashMap<>(42);
private static final Path FOUND_SOULS_FILE = SkyblockerMod.CONFIG_DIR.resolve("found_enigma_souls.json");
- private static final Object2ObjectOpenHashMap<String, ObjectOpenHashSet<BlockPos>> FOUND_SOULS = new Object2ObjectOpenHashMap<>();
private static final float[] GREEN = DyeColor.GREEN.getColorComponents();
private static final float[] RED = DyeColor.RED.getColorComponents();
@@ -64,7 +59,8 @@ public class EnigmaSouls {
for (int i = 0; i < waypoints.size(); i++) {
JsonObject waypoint = waypoints.get(i).getAsJsonObject();
- SOUL_WAYPOINTS[i] = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt());
+ BlockPos pos = new BlockPos(waypoint.get("x").getAsInt(), waypoint.get("y").getAsInt(), waypoint.get("z").getAsInt());
+ SOUL_WAYPOINTS.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, GREEN, RED));
}
} catch (IOException e) {
@@ -74,13 +70,9 @@ public class EnigmaSouls {
//Load found souls
try (BufferedReader reader = Files.newBufferedReader(FOUND_SOULS_FILE)) {
for (Map.Entry<String, JsonElement> profile : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = new ObjectOpenHashSet<>();
-
for (JsonElement foundSoul : profile.getValue().getAsJsonArray().asList()) {
- foundSoulsOnProfile.add(PosUtils.parsePosString(foundSoul.getAsString()));
+ SOUL_WAYPOINTS.get(PosUtils.parsePosString(foundSoul.getAsString())).setFound();
}
-
- FOUND_SOULS.put(profile.getKey(), foundSoulsOnProfile);
}
} catch (NoSuchFileException ignored) {
} catch (IOException e) {
@@ -90,9 +82,16 @@ public class EnigmaSouls {
}
static void save(MinecraftClient client) {
- JsonObject json = new JsonObject();
+ Map<String, Set<BlockPos>> foundSouls = new HashMap<>();
+ for (ProfileAwareWaypoint soul : SOUL_WAYPOINTS.values()) {
+ for (String profile : soul.foundProfiles) {
+ foundSouls.computeIfAbsent(profile, profile_ -> new HashSet<>());
+ foundSouls.get(profile).add(soul.pos);
+ }
+ }
- for (Map.Entry<String, ObjectOpenHashSet<BlockPos>> foundSoulsForProfile : FOUND_SOULS.entrySet()) {
+ JsonObject json = new JsonObject();
+ for (Map.Entry<String, Set<BlockPos>> foundSoulsForProfile : foundSouls.entrySet()) {
JsonArray foundSoulsJson = new JsonArray();
for (BlockPos foundSoul : foundSoulsForProfile.getValue()) {
@@ -109,15 +108,15 @@ public class EnigmaSouls {
}
}
- static void render(WorldRenderContext wrc) {
+ static void render(WorldRenderContext context) {
SkyblockerConfig.Rift config = SkyblockerConfigManager.get().locations.rift;
if (Utils.isInTheRift() && config.enigmaSoulWaypoints && soulsLoaded.isDone()) {
- for (BlockPos pos : SOUL_WAYPOINTS) {
- if (isSoulMissing(pos)) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, GREEN, 0.5f);
+ for (Waypoint soul : SOUL_WAYPOINTS.values()) {
+ if (soul.shouldRender()) {
+ soul.render(context);
} else if (config.highlightFoundEnigmaSouls) {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(wrc, pos, RED, 0.5f);
+ soul.render(context);
}
}
}
@@ -127,7 +126,8 @@ public class EnigmaSouls {
if (Utils.isInTheRift() && !overlay) {
String message = text.getString();
- if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!")) markClosestSoulAsFound();
+ if (message.equals("You have already found that Enigma Soul!") || Formatting.strip(message).equals("SOUL! You unlocked an Enigma Soul!"))
+ markClosestSoulAsFound();
}
}
@@ -136,13 +136,13 @@ public class EnigmaSouls {
.then(literal("rift")
.then(literal("enigmaSouls")
.then(literal("markAllFound").executes(context -> {
- markAllFound();
+ SOUL_WAYPOINTS.values().forEach(Waypoint::setFound);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllFound")));
return Command.SINGLE_SUCCESS;
}))
.then(literal("markAllMissing").executes(context -> {
- markAllMissing();
+ SOUL_WAYPOINTS.values().forEach(Waypoint::setMissing);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.rift.enigmaSouls.markAllMissing")));
return Command.SINGLE_SUCCESS;
@@ -154,30 +154,10 @@ public class EnigmaSouls {
if (!soulsLoaded.isDone() || player == null) return;
- Arrays.stream(SOUL_WAYPOINTS)
- .filter(EnigmaSouls::isSoulMissing)
- .min(Comparator.comparingDouble(soulPos -> soulPos.getSquaredDistance(player.getPos())))
- .filter(soulPos -> soulPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(soulPos -> {
- FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>());
- FOUND_SOULS.get(Utils.getProfile()).add(soulPos);
- });
- }
-
- private static boolean isSoulMissing(BlockPos soulPos) {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile());
-
- return foundSoulsOnProfile == null || !foundSoulsOnProfile.contains(soulPos);
- }
-
- private static void markAllFound() {
- FOUND_SOULS.computeIfAbsent(Utils.getProfile(), profile -> new ObjectOpenHashSet<>());
- FOUND_SOULS.get(Utils.getProfile()).addAll(List.of(SOUL_WAYPOINTS));
- }
-
- private static void markAllMissing() {
- ObjectOpenHashSet<BlockPos> foundSoulsOnProfile = FOUND_SOULS.get(Utils.getProfile());
-
- if (foundSoulsOnProfile != null) foundSoulsOnProfile.clear();
+ SOUL_WAYPOINTS.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(soul -> soul.pos.getSquaredDistance(player.getPos())))
+ .filter(soul -> soul.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
index 7dda741f..83199e99 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/rift/MirrorverseWaypoints.java
@@ -6,7 +6,7 @@ import com.google.gson.JsonParser;
import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.DyeColor;
@@ -18,13 +18,15 @@ import org.slf4j.LoggerFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
public class MirrorverseWaypoints {
private static final Logger LOGGER = LoggerFactory.getLogger("skyblocker");
+ private static final Supplier<Waypoint.Type> WAYPOINT_TYPE = () -> Waypoint.Type.HIGHLIGHT;
private static final Identifier WAYPOINTS_JSON = new Identifier(SkyblockerMod.NAMESPACE, "rift/mirrorverse_waypoints.json");
- private static final BlockPos[] LAVA_PATH_WAYPOINTS = new BlockPos[107];
- private static final BlockPos[] UPSIDE_DOWN_WAYPOINTS = new BlockPos[66];
- private static final BlockPos[] TURBULATOR_WAYPOINTS = new BlockPos[27];
+ private static Waypoint[] LAVA_PATH_WAYPOINTS;
+ private static Waypoint[] UPSIDE_DOWN_WAYPOINTS;
+ private static Waypoint[] TURBULATOR_WAYPOINTS;
private static final float[] COLOR_COMPONENTS = DyeColor.RED.getColorComponents();
private static CompletableFuture<Void> waypointsLoaded;
@@ -35,51 +37,44 @@ public class MirrorverseWaypoints {
static void load(MinecraftClient client) {
waypointsLoaded = CompletableFuture.runAsync(() -> {
try (BufferedReader reader = client.getResourceManager().openAsReader(WAYPOINTS_JSON)) {
- JsonObject file = JsonParser.parseReader(reader).getAsJsonObject();
- JsonArray sections = file.get("sections").getAsJsonArray();
+ JsonArray sections = JsonParser.parseReader(reader).getAsJsonObject().get("sections").getAsJsonArray();
/// Lava Path
- JsonArray lavaPathWaypoints = sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < lavaPathWaypoints.size(); i++) {
- JsonObject point = lavaPathWaypoints.get(i).getAsJsonObject();
- LAVA_PATH_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ LAVA_PATH_WAYPOINTS = loadWaypoints(sections.get(0).getAsJsonObject().get("waypoints").getAsJsonArray());
/// Upside Down Parkour
- JsonArray upsideDownParkourWaypoints = sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < upsideDownParkourWaypoints.size(); i++) {
- JsonObject point = upsideDownParkourWaypoints.get(i).getAsJsonObject();
- UPSIDE_DOWN_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ UPSIDE_DOWN_WAYPOINTS = loadWaypoints(sections.get(1).getAsJsonObject().get("waypoints").getAsJsonArray());
/// Turbulator Parkour
- JsonArray turbulatorParkourWaypoints = sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray();
-
- for (int i = 0; i < turbulatorParkourWaypoints.size(); i++) {
- JsonObject point = turbulatorParkourWaypoints.get(i).getAsJsonObject();
- TURBULATOR_WAYPOINTS[i] = new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt());
- }
+ TURBULATOR_WAYPOINTS = loadWaypoints(sections.get(2).getAsJsonObject().get("waypoints").getAsJsonArray());
} catch (IOException e) {
LOGGER.error("[Skyblocker] Mirrorverse Waypoints failed to load ;(", e);
}
});
}
+ private static Waypoint[] loadWaypoints(JsonArray waypointsJson) {
+ Waypoint[] waypoints = new Waypoint[waypointsJson.size()];
+ for (int i = 0; i < waypointsJson.size(); i++) {
+ JsonObject point = waypointsJson.get(i).getAsJsonObject();
+ waypoints[i] = new Waypoint(new BlockPos(point.get("x").getAsInt(), point.get("y").getAsInt(), point.get("z").getAsInt()), WAYPOINT_TYPE, COLOR_COMPONENTS, false);
+ }
+ return waypoints;
+ }
+
protected static void render(WorldRenderContext wrc) {
//I would also check for the mirrorverse location but the scoreboard stuff is not performant at all...
if (Utils.isInTheRift() && SkyblockerConfigManager.get().locations.rift.mirrorverseWaypoints && waypointsLoaded.isDone()) {
- for (BlockPos pos : LAVA_PATH_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : LAVA_PATH_WAYPOINTS) {
+ waypoint.render(wrc);
}
- for (BlockPos pos : UPSIDE_DOWN_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : UPSIDE_DOWN_WAYPOINTS) {
+ waypoint.render(wrc);
}
- for (BlockPos pos : TURBULATOR_WAYPOINTS) {
- RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+ for (Waypoint waypoint : TURBULATOR_WAYPOINTS) {
+ waypoint.render(wrc);
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
index 9c058a4f..c2c952cf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/Shortcuts.java
@@ -21,6 +21,9 @@ import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Type;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
+import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
@@ -30,7 +33,7 @@ import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.lit
public class Shortcuts {
private static final Logger LOGGER = LoggerFactory.getLogger(Shortcuts.class);
- private static final File SHORTCUTS_FILE = SkyblockerMod.CONFIG_DIR.resolve("shortcuts.json").toFile();
+ private static final Path SHORTCUTS_FILE = SkyblockerMod.CONFIG_DIR.resolve("shortcuts.json");
@Nullable
private static CompletableFuture<Void> shortcutsLoaded;
public static final Map<String, String> commands = new HashMap<>();
@@ -52,7 +55,7 @@ public class Shortcuts {
return;
}
shortcutsLoaded = CompletableFuture.runAsync(() -> {
- try (BufferedReader reader = new BufferedReader(new FileReader(SHORTCUTS_FILE))) {
+ try (BufferedReader reader = Files.newBufferedReader(SHORTCUTS_FILE)) {
Type shortcutsType = new TypeToken<Map<String, Map<String, String>>>() {
}.getType();
Map<String, Map<String, String>> shortcuts = SkyblockerMod.GSON.fromJson(reader, shortcutsType);
@@ -61,7 +64,7 @@ public class Shortcuts {
commands.putAll(shortcuts.get("commands"));
commandArgs.putAll(shortcuts.get("commandArgs"));
LOGGER.info("[Skyblocker] Loaded {} command shortcuts and {} command argument shortcuts", commands.size(), commandArgs.size());
- } catch (FileNotFoundException e) {
+ } catch (NoSuchFileException e) {
registerDefaultShortcuts();
LOGGER.warn("[Skyblocker] Shortcuts file not found, using default shortcuts. This is normal when using for the first time.");
} catch (IOException e) {
@@ -140,7 +143,7 @@ public class Shortcuts {
JsonObject shortcutsJson = new JsonObject();
shortcutsJson.add("commands", SkyblockerMod.GSON.toJsonTree(commands));
shortcutsJson.add("commandArgs", SkyblockerMod.GSON.toJsonTree(commandArgs));
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SHORTCUTS_FILE))) {
+ try (BufferedWriter writer = Files.newBufferedWriter(SHORTCUTS_FILE)) {
SkyblockerMod.GSON.toJson(shortcutsJson, writer);
LOGGER.info("[Skyblocker] Saved {} command shortcuts and {} command argument shortcuts", commands.size(), commandArgs.size());
} catch (IOException e) {
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
index 196ad0d6..a5f8ae2d 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
@@ -19,7 +19,7 @@ public class ShortcutsConfigScreen extends Screen {
private boolean initialized;
private double scrollAmount;
private final Screen parent;
-
+
public ShortcutsConfigScreen() {
this(null);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
index fba447ea..bc4f98c2 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/special/SpecialEffects.java
@@ -1,8 +1,8 @@
package de.hysky.skyblocker.skyblock.special;
-import com.mojang.blaze3d.systems.RenderSystem;
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.message.v1.ClientReceiveMessageEvents;
import net.minecraft.client.MinecraftClient;
import net.minecraft.enchantment.Enchantments;
@@ -58,15 +58,10 @@ public class SpecialEffects {
ItemStack stack = getStackFromName(matcher.group("item"));
if (!stack.isEmpty()) {
- if (RenderSystem.isOnRenderThread()) {
+ RenderHelper.runOnRenderThread(() -> {
client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
client.gameRenderer.showFloatingItem(stack);
- } else {
- RenderSystem.recordRenderCall(() -> {
- client.particleManager.addEmitter(client.player, ParticleTypes.PORTAL, 30);
- client.gameRenderer.showFloatingItem(stack);
- });
- }
+ });
}
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java
new file mode 100644
index 00000000..0de3e45f
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Colors.java
@@ -0,0 +1,14 @@
+package de.hysky.skyblocker.skyblock.tabhud.util;
+
+import net.minecraft.util.math.MathHelper;
+
+public class Colors {
+
+ /**
+ * @param pcnt Percentage between 0% and 100%, NOT 0-1!
+ * @return an int representing a color, where 100% = green and 0% = red
+ */
+ public static int pcntToCol(float pcnt) {
+ return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
index 24883d77..82394a78 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/Ico.java
@@ -10,6 +10,7 @@ public class Ico {
public static final ItemStack MAP = new ItemStack(Items.FILLED_MAP);
public static final ItemStack NTAG = new ItemStack(Items.NAME_TAG);
public static final ItemStack EMERALD = new ItemStack(Items.EMERALD);
+ public static final ItemStack AMETHYST_SHARD = new ItemStack(Items.AMETHYST_SHARD);
public static final ItemStack CLOCK = new ItemStack(Items.CLOCK);
public static final ItemStack DIASWORD = new ItemStack(Items.DIAMOND_SWORD);
public static final ItemStack DBUSH = new ItemStack(Items.DEAD_BUSH);
@@ -48,8 +49,10 @@ public class Ico {
public static final ItemStack B_ROD = new ItemStack(Items.BLAZE_ROD);
public static final ItemStack BOW = new ItemStack(Items.BOW);
public static final ItemStack COPPER = new ItemStack(Items.COPPER_INGOT);
+ public static final ItemStack NETHERITE_UPGRADE_ST = new ItemStack(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE);
public static final ItemStack COMPOSTER = new ItemStack(Items.COMPOSTER);
public static final ItemStack SAPLING = new ItemStack(Items.OAK_SAPLING);
+ public static final ItemStack SEEDS = new ItemStack(Items.WHEAT_SEEDS);
public static final ItemStack MILESTONE = new ItemStack(Items.LODESTONE);
public static final ItemStack PICKAXE = new ItemStack(Items.IRON_PICKAXE);
public static final ItemStack NETHER_STAR = new ItemStack(Items.NETHER_STAR);
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
index f577f2d3..3ef968a3 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
@@ -35,7 +35,7 @@ public class PlayerListMgr {
ClientPlayNetworkHandler cpnwh = MinecraftClient.getInstance().getNetworkHandler();
- // check is needed, else game crash on server leave
+ // check is needed, else game crashes on server leave
if (cpnwh != null) {
playerList = cpnwh.getPlayerList().stream().sorted(PlayerListHudAccessor.getOrdering()).toList();
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
index e8bf91ab..a5fb4d32 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/CommsWidget.java
@@ -3,14 +3,14 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import de.hysky.skyblocker.skyblock.tabhud.widget.component.IcoTextComponent;
-import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
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;
+import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
// this widget shows the status of the king's commissions.
// (dwarven mines and crystal hollows)
@@ -47,17 +47,13 @@ public class CommsWidget extends Widget {
String progress = m.group("progress");
if (progress.equals("DONE")) {
- pc = new ProgressComponent(Ico.BOOK, Text.of(name), Text.of(progress), 100f, pcntToCol(100));
+ pc = new ProgressComponent(Ico.BOOK, Text.of(name), Text.of(progress), 100f, Colors.pcntToCol(100));
} else {
float pcnt = Float.parseFloat(progress.substring(0, progress.length() - 1));
- pc = new ProgressComponent(Ico.BOOK, Text.of(name), pcnt, pcntToCol(pcnt));
+ pc = new ProgressComponent(Ico.BOOK, Text.of(name), pcnt, Colors.pcntToCol(pcnt));
}
this.addComponent(pc);
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
index fbeb5ae5..f50b617b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ComposterWidget.java
@@ -2,7 +2,7 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
-
+import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -20,11 +20,11 @@ public class ComposterWidget extends Widget {
@Override
public void updateContent() {
- this.addSimpleIcoText(Ico.SAPLING, "Organic Matter:", Formatting.YELLOW, 48);
- this.addSimpleIcoText(Ico.FURNACE, "Fuel:", Formatting.BLUE, 49);
- this.addSimpleIcoText(Ico.CLOCK, "Time Left:", Formatting.RED, 50);
- this.addSimpleIcoText(Ico.COMPOSTER, "Stored Compost:", Formatting.DARK_GREEN, 51);
+ int offset = (PlayerListMgr.strAt(46) != null) ? 1 : 0;
+ this.addSimpleIcoText(Ico.SAPLING, "Organic Matter:", Formatting.YELLOW, 48 + offset);
+ this.addSimpleIcoText(Ico.FURNACE, "Fuel:", Formatting.BLUE, 49 + offset);
+ this.addSimpleIcoText(Ico.CLOCK, "Time Left:", Formatting.RED, 50 + offset);
+ this.addSimpleIcoText(Ico.COMPOSTER, "Stored Compost:", Formatting.DARK_GREEN, 51 + offset);
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
index 1b3b8644..53f84f71 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/DungeonPuzzleWidget.java
@@ -37,16 +37,21 @@ public class DungeonPuzzleWidget extends Widget {
if (m == null) {
break;
}
+
+ Formatting statcol = switch (m.group("status")) {
+ case "✦" -> Formatting.GOLD; // Unsolved
+ case "✔" -> Formatting.GREEN; // Solved
+ case "✖" -> Formatting.RED; // Failed
+ default -> Formatting.WHITE; // Who knows if they'll add another puzzle state or not?
+ };
+
Text t = Text.literal(m.group("name") + ": ")
.append(Text.literal("[").formatted(Formatting.GRAY))
- .append(m.group("status"))
+ .append(Text.literal(m.group("status")).formatted(statcol, Formatting.BOLD))
.append(Text.literal("]").formatted(Formatting.GRAY));
IcoTextComponent itc = new IcoTextComponent(Ico.SIGN, t);
this.addComponent(itc);
pos++;
- // code points for puzzle status chars unsolved and solved: 10022, 10004
- // not sure which one is which
- // still need to find out codepoint for the puzzle failed char
}
if (pos == 48) {
this.addComponent(
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
index 0211cbd6..e08b4acf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/FireSaleWidget.java
@@ -3,14 +3,13 @@ package de.hysky.skyblocker.skyblock.tabhud.widget;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
-
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
-import net.minecraft.util.math.MathHelper;
import net.minecraft.util.Formatting;
// this widget shows info about fire sales when in the hub.
@@ -55,14 +54,10 @@ public class FireSaleWidget extends Widget {
float total = Float.parseFloat(m.group("total")) * 1000;
Text prgressTxt = Text.literal(String.format("%s/%.0f", avail, total));
float pcnt = (Float.parseFloat(avail) / (total)) * 100f;
- ProgressComponent pc = new ProgressComponent(Ico.GOLD, itemTxt, prgressTxt, pcnt, pcntToCol(pcnt));
+ ProgressComponent pc = new ProgressComponent(Ico.GOLD, itemTxt, prgressTxt, pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb( pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
index 1a4683f5..adae7daf 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/ForgeWidget.java
@@ -69,7 +69,11 @@ public class ForgeWidget extends Widget {
c = new IcoFatTextComponent();
} else {
l1 = Text.literal(parts[0].substring(3)).formatted(Formatting.YELLOW);
- l2 = Text.literal("Done in: ").formatted(Formatting.GRAY).append(Text.literal(parts[1]).formatted(Formatting.WHITE));
+ if (parts[1].equals("Ready!")) {
+ l2 = Text.literal("Done!").formatted(Formatting.GREEN);
+ } else {
+ l2 = Text.literal("Done in: ").formatted(Formatting.GRAY).append(Text.literal(parts[1]).formatted(Formatting.WHITE));
+ }
c = new IcoFatTextComponent(Ico.FIRE, l1, l2);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
index 221f8b08..b6b65896 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenServerWidget.java
@@ -6,7 +6,7 @@ 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;
-
+import de.hysky.skyblocker.utils.Constants;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
@@ -14,13 +14,14 @@ import net.minecraft.util.Formatting;
// this widget shows info about the garden server
public class GardenServerWidget extends Widget {
-
private static final MutableText TITLE = Text.literal("Server Info").formatted(Formatting.DARK_AQUA,
Formatting.BOLD);
+ //From the armor trim tooltip
+ private static final int COPPER_COLOR = 11823181;
// match the next visitor in the garden
// group 1: visitor name
- private static final Pattern VISITOR_PATTERN = Pattern.compile("Next Visitor: (?<vis>.*)");
+ private static final Pattern VISITOR_PATTERN = Pattern.compile("Visitors: (?<vis>.*)");
public GardenServerWidget() {
super(TITLE, Formatting.DARK_AQUA.getColorValue());
@@ -31,17 +32,29 @@ public class GardenServerWidget extends Widget {
this.addSimpleIcoText(Ico.MAP, "Area:", Formatting.DARK_AQUA, 41);
this.addSimpleIcoText(Ico.NTAG, "Server ID:", Formatting.GRAY, 42);
this.addSimpleIcoText(Ico.EMERALD, "Gems:", Formatting.GREEN, 43);
- this.addSimpleIcoText(Ico.COPPER, "Copper:", Formatting.GOLD, 44);
- Matcher m = PlayerListMgr.regexAt(45, VISITOR_PATTERN);
+ Text copperText = Widget.simpleEntryText(44, "Copper:", Formatting.WHITE);
+ ((MutableText) copperText.getSiblings().get(0)).styled(Constants.WITH_COLOR.apply(COPPER_COLOR));
+
+ this.addComponent(new IcoTextComponent(Ico.COPPER, copperText));
+
+ boolean hasPesthunterBonus = PlayerListMgr.strAt(46) != null;
+
+ if (hasPesthunterBonus) {
+ this.addComponent(new IcoTextComponent(Ico.NETHERITE_UPGRADE_ST, PlayerListMgr.textAt(46)));
+ }
+
+ int offset = hasPesthunterBonus ? 1 : 0;
+
+ Matcher m = PlayerListMgr.regexAt(53 + offset, VISITOR_PATTERN);
if (m == null ) {
this.addComponent(new IcoTextComponent());
return;
}
- String vis = m.group("vis");
+ String vis = m.group("vis").replaceAll("[()]*", "");
Formatting col;
- if (vis.equals("Not Unlocked!")) {
+ if (vis.equals("Not Unlocked!") || vis.equals("Queue Full!")) {
col = Formatting.RED;
} else {
col = Formatting.GREEN;
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
index 41eee8d6..75652b33 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenSkillsWidget.java
@@ -26,6 +26,8 @@ public class GardenSkillsWidget extends Widget {
private static final Pattern SKILL_PATTERN = Pattern
.compile("Skills: (?<skill>[A-Za-z]* [0-9]*): (?<progress>[0-9.MAX]*)%?");
+ private static final Pattern GARDEN_LEVEL_PATTERN = Pattern.compile("Garden Level: (?<level>[IVX0-9]+)(?: \\((?<progress>[0-9.]+)% to [IVX0-9]+\\))?");
+
// same, more or less
private static final Pattern MS_PATTERN = Pattern
.compile("Milestone: (?<milestone>[A-Za-z ]* [0-9]*): (?<progress>[0-9.]*)%");
@@ -36,26 +38,46 @@ public class GardenSkillsWidget extends Widget {
@Override
public void updateContent() {
- ProgressComponent pc;
- Matcher m = PlayerListMgr.regexAt(66, SKILL_PATTERN);
- if (m == null) {
- pc = new ProgressComponent();
+ ProgressComponent spc;
+ Matcher skillMatcher = PlayerListMgr.regexAt(66, SKILL_PATTERN);
+ if (skillMatcher == null) {
+ spc = new ProgressComponent();
} else {
- String strpcnt = m.group("progress");
- String skill = m.group("skill");
+ String strpcnt = skillMatcher.group("progress");
+ String skill = skillMatcher.group("skill");
if (strpcnt.equals("MAX")) {
- pc = new ProgressComponent(Ico.LANTERN, Text.of(skill), Text.of("MAX"), 100f,
+ spc = new ProgressComponent(Ico.LANTERN, Text.of(skill), Text.of("MAX"), 100f,
Formatting.RED.getColorValue());
} else {
float pcnt = Float.parseFloat(strpcnt);
- pc = new ProgressComponent(Ico.LANTERN, Text.of(skill), pcnt,
+ spc = new ProgressComponent(Ico.LANTERN, Text.of(skill), pcnt,
Formatting.GOLD.getColorValue());
}
}
- this.addComponent(pc);
+ this.addComponent(spc);
+
+ ProgressComponent glpc;
+ Matcher glMatcher = PlayerListMgr.regexAt(45, GARDEN_LEVEL_PATTERN);
+
+ if (glMatcher == null) {
+ glpc = new ProgressComponent();
+ } else {
+ String level = glMatcher.group("level");
+
+ if (level.equals("15") || level.equals("XV")) {
+ glpc = new ProgressComponent(Ico.SEEDS, Text.literal("Garden Level " + level), 100f, Formatting.RED.getColorValue());
+ } else {
+ String strpcnt = glMatcher.group("progress");
+ float pcnt = Float.parseFloat(strpcnt);
+
+ glpc = new ProgressComponent(Ico.SEEDS, Text.literal("Garden Level " + level), pcnt, Formatting.DARK_GREEN.getColorValue());
+ }
+ }
+
+ this.addComponent(glpc);
Text speed = Widget.simpleEntryText(67, "SPD", Formatting.WHITE);
IcoTextComponent spd = new IcoTextComponent(Ico.SUGAR, speed);
@@ -66,22 +88,21 @@ public class GardenSkillsWidget extends Widget {
tc.addToCell(0, 0, spd);
tc.addToCell(1, 0, ffo);
this.addComponent(tc);
+
+ this.addComponent(new IcoTextComponent(Ico.HOE, PlayerListMgr.textAt(70)));
ProgressComponent pc2;
- m = PlayerListMgr.regexAt(69, MS_PATTERN);
- if (m == null) {
+ Matcher milestoneMatcher = PlayerListMgr.regexAt(69, MS_PATTERN);
+ if (milestoneMatcher == null) {
pc2 = new ProgressComponent();
} else {
- String strpcnt = m.group("progress");
- String milestone = m.group("milestone");
+ String strpcnt = milestoneMatcher.group("progress");
+ String milestone = milestoneMatcher.group("milestone");
float pcnt = Float.parseFloat(strpcnt);
pc2 = new ProgressComponent(Ico.MILESTONE, Text.of(milestone), pcnt,
Formatting.GREEN.getColorValue());
-
}
this.addComponent(pc2);
-
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
index cfbd6cd0..2b0036ad 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
@@ -15,16 +15,17 @@ public class GardenVisitorsWidget extends Widget {
@Override
public void updateContent() {
- if (PlayerListMgr.textAt(54) == null) {
+ int offset = (PlayerListMgr.strAt(46) != null) ? 1 : 0;
+
+ if (PlayerListMgr.textAt(54 + offset) == null) {
this.addComponent(new PlainTextComponent(Text.literal("No visitors!").formatted(Formatting.GRAY)));
return;
}
- for (int i = 54; i < 59; i++) {
+ for (int i = 54 + offset; i < 59 + offset; i++) {
String text = PlayerListMgr.strAt(i);
if (text != null)
this.addComponent(new PlainTextComponent(Text.literal(text)));
}
-
}
}
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 5ae0bd3d..472e6d61 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,6 +1,8 @@
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;
@@ -19,6 +21,9 @@ public class JacobsContestWidget extends Widget {
private static final MutableText TITLE = Text.literal("Jacob's Contest").formatted(Formatting.YELLOW,
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 HashMap<String, ItemStack> FARM_DATA = new HashMap<>();
// again, there HAS to be a better way to do this
@@ -41,22 +46,27 @@ public class JacobsContestWidget extends Widget {
@Override
public void updateContent() {
- this.addSimpleIcoText(Ico.CLOCK, "Starts in:", Formatting.GOLD, 76);
+ Text jacobStatus = PlayerListMgr.textAt(76);
+
+ if (jacobStatus.getString().equals("ACTIVE")) {
+ this.addComponent(new IcoTextComponent(Ico.CLOCK, jacobStatus));
+ } else {
+ this.addSimpleIcoText(Ico.CLOCK, "Starts in:", Formatting.GOLD, 76);
+ }
TableComponent tc = new TableComponent(1, 3, Formatting.YELLOW .getColorValue());
for (int i = 77; i < 80; i++) {
- String item = PlayerListMgr.strAt(i);
+ Matcher item = PlayerListMgr.regexAt(i, CROP_PATTERN);
IcoTextComponent itc;
if (item == null) {
itc = new IcoTextComponent();
} else {
- itc = new IcoTextComponent(FARM_DATA.get(item), Text.of(item));
+ 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));
}
tc.addToCell(0, i - 77, itc);
}
this.addComponent(tc);
-
}
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
index 44635fbe..ec176a98 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/PowderWidget.java
@@ -22,7 +22,7 @@ public class PowderWidget extends Widget {
@Override
public void updateContent() {
this.addSimpleIcoText(Ico.MITHRIL, "Mithril:", Formatting.AQUA, 46);
- this.addSimpleIcoText(Ico.EMERALD, "Gemstone:", Formatting.DARK_PURPLE, 47);
+ this.addSimpleIcoText(Ico.AMETHYST_SHARD, "Gemstone:", Formatting.DARK_PURPLE, 47);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
index 6aa363c9..442f12ca 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/hud/HudCommsWidget.java
@@ -2,16 +2,16 @@ package de.hysky.skyblocker.skyblock.tabhud.widget.hud;
import java.util.List;
-import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.dwarven.DwarvenHud.Commission;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
+import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.Component;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
// this widget shows the status of the king's commissions.
// (dwarven mines and crystal hollows)
@@ -56,7 +56,7 @@ public class HudCommsWidget extends Widget {
Component comp;
if (isFancy) {
- comp = new ProgressComponent(Ico.BOOK, c, p, pcntToCol(p));
+ comp = new ProgressComponent(Ico.BOOK, c, p, Colors.pcntToCol(p));
} else {
comp = new PlainTextComponent(
Text.literal(comm.commission() + ": ")
@@ -66,8 +66,4 @@ public class HudCommsWidget extends Widget {
}
}
- private int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
index 93ade5cb..6cd7736b 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/tabhud/widget/rift/RiftProgressWidget.java
@@ -3,15 +3,15 @@ package de.hysky.skyblocker.skyblock.tabhud.widget.rift;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
+import de.hysky.skyblocker.skyblock.tabhud.util.Colors;
import de.hysky.skyblocker.skyblock.tabhud.util.Ico;
import de.hysky.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import de.hysky.skyblocker.skyblock.tabhud.widget.Widget;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
import de.hysky.skyblocker.skyblock.tabhud.widget.component.ProgressComponent;
import net.minecraft.text.MutableText;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-import net.minecraft.util.math.MathHelper;
public class RiftProgressWidget extends Widget {
@@ -75,10 +75,6 @@ public class RiftProgressWidget extends Widget {
}
- private static int pcntToCol(float pcnt) {
- return MathHelper.hsvToRgb(pcnt / 300f, 0.9f, 0.9f);
- }
-
private void addTimecharmsComponent(int pos) {
Matcher m = PlayerListMgr.regexAt(pos, TIMECHARMS_PATTERN);
@@ -88,7 +84,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.NETHER_STAR, Text.literal("Timecharms"), progressText,
- pcnt, pcntToCol(pcnt));
+ pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
@@ -102,7 +98,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.HEART_OF_THE_SEA, Text.literal("Enigma Souls"),
- progressText, pcnt, pcntToCol(pcnt));
+ progressText, pcnt, Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
@@ -116,7 +112,7 @@ public class RiftProgressWidget extends Widget {
Text progressText = Text.literal(current + "/" + total);
ProgressComponent pc = new ProgressComponent(Ico.BONE, Text.literal("Montezuma"), progressText, pcnt,
- pcntToCol(pcnt));
+ Colors.pcntToCol(pcnt));
this.addComponent(pc);
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
index cef17d8e..f0e94770 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/FairySouls.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/FairySouls.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -12,7 +12,8 @@ import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.NEURepoManager;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
@@ -29,19 +30,24 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
import java.util.stream.Collectors;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class FairySouls {
private static final Logger LOGGER = LoggerFactory.getLogger(FairySouls.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static CompletableFuture<Void> fairySoulsLoaded;
private static int maxSouls = 0;
- private static final Map<String, Set<BlockPos>> fairySouls = new HashMap<>();
- private static final Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>();
+ private static final Map<String, Map<BlockPos, ProfileAwareWaypoint>> fairySouls = new HashMap<>();
@SuppressWarnings("UnusedReturnValue")
public static CompletableFuture<Void> runAsyncAfterFairySoulsLoad(Runnable runnable) {
@@ -67,32 +73,41 @@ public class FairySouls {
private static void loadFairySouls() {
fairySoulsLoaded = NEURepoManager.runAsyncAfterLoad(() -> {
maxSouls = NEURepoManager.NEU_REPO.getConstants().getFairySouls().getMaxSouls();
- NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairySoulsForLocation) -> fairySouls.put(location, fairySoulsForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableSet())));
- LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size());
+ NEURepoManager.NEU_REPO.getConstants().getFairySouls().getSoulLocations().forEach((location, fairiesForLocation) -> fairySouls.put(location, fairiesForLocation.stream().map(coordinate -> new BlockPos(coordinate.getX(), coordinate.getY(), coordinate.getZ())).collect(Collectors.toUnmodifiableMap(pos -> pos, pos -> new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.GREEN.getColorComponents(), DyeColor.RED.getColorComponents())))));
+ LOGGER.debug("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size());
- try (BufferedReader reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile()))) {
+ try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) {
for (Map.Entry<String, JsonElement> foundFairiesForProfileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- Map<String, Set<BlockPos>> foundFairiesForProfile = new HashMap<>();
for (Map.Entry<String, JsonElement> foundFairiesForLocationJson : foundFairiesForProfileJson.getValue().getAsJsonObject().asMap().entrySet()) {
- Set<BlockPos> foundFairiesForLocation = new HashSet<>();
+ String profile = foundFairiesForLocationJson.getKey();
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(profile);
for (JsonElement foundFairy : foundFairiesForLocationJson.getValue().getAsJsonArray().asList()) {
- foundFairiesForLocation.add(PosUtils.parsePosString(foundFairy.getAsString()));
+ fairiesForLocation.get(PosUtils.parsePosString(foundFairy.getAsString())).setFound(profile);
}
- foundFairiesForProfile.put(foundFairiesForLocationJson.getKey(), foundFairiesForLocation);
}
- foundFairies.put(foundFairiesForProfileJson.getKey(), foundFairiesForProfile);
}
LOGGER.debug("[Skyblocker] Loaded found fairy souls");
- } catch (FileNotFoundException ignored) {
+ } catch (NoSuchFileException ignored) {
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to load found fairy souls", e);
}
- LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations and {} found fairy souls across {} locations in {} profiles", fairySouls.values().stream().mapToInt(Set::size).sum(), fairySouls.size(), foundFairies.values().stream().map(Map::values).flatMap(Collection::stream).mapToInt(Set::size).sum(), foundFairies.values().stream().mapToInt(Map::size).sum(), foundFairies.size());
+ LOGGER.info("[Skyblocker] Loaded {} fairy souls across {} locations", fairySouls.values().stream().mapToInt(Map::size).sum(), fairySouls.size());
});
}
private static void saveFoundFairySouls(MinecraftClient client) {
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json").toFile()))) {
+ Map<String, Map<String, Set<BlockPos>>> foundFairies = new HashMap<>();
+ for (Map.Entry<String, Map<BlockPos, ProfileAwareWaypoint>> fairiesForLocation : fairySouls.entrySet()) {
+ for (ProfileAwareWaypoint fairySoul : fairiesForLocation.getValue().values()) {
+ for (String profile : fairySoul.foundProfiles) {
+ foundFairies.computeIfAbsent(profile, profile_ -> new HashMap<>());
+ foundFairies.get(profile).computeIfAbsent(fairiesForLocation.getKey(), location_ -> new HashSet<>());
+ foundFairies.get(profile).get(fairiesForLocation.getKey()).add(fairySoul.pos);
+ }
+ }
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_fairy_souls.json"))) {
JsonObject foundFairiesJson = new JsonObject();
for (Map.Entry<String, Map<String, Set<BlockPos>>> foundFairiesForProfile : foundFairies.entrySet()) {
JsonObject foundFairiesForProfileJson = new JsonObject();
@@ -106,7 +121,6 @@ public class FairySouls {
foundFairiesJson.add(foundFairiesForProfile.getKey(), foundFairiesForProfileJson);
}
SkyblockerMod.GSON.toJson(foundFairiesJson, writer);
- writer.close();
LOGGER.info("[Skyblocker] Saved found fairy souls");
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to write found fairy souls to file", e);
@@ -132,13 +146,12 @@ public class FairySouls {
SkyblockerConfig.FairySouls fairySoulsConfig = SkyblockerConfigManager.get().general.fairySouls;
if (fairySoulsConfig.enableFairySoulsHelper && fairySoulsLoaded.isDone() && fairySouls.containsKey(Utils.getLocationRaw())) {
- for (BlockPos fairySoulPos : fairySouls.get(Utils.getLocationRaw())) {
- boolean fairySoulNotFound = isFairySoulMissing(fairySoulPos);
- if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoulPos.getSquaredDistance(context.camera().getPos()) > 2500) {
+ for (Waypoint fairySoul : fairySouls.get(Utils.getLocationRaw()).values()) {
+ boolean fairySoulNotFound = fairySoul.shouldRender();
+ if (!fairySoulsConfig.highlightFoundSouls && !fairySoulNotFound || fairySoulsConfig.highlightOnlyNearbySouls && fairySoul.pos.getSquaredDistance(context.camera().getPos()) > 2500) {
continue;
}
- float[] colorComponents = fairySoulNotFound ? DyeColor.GREEN.getColorComponents() : DyeColor.RED.getColorComponents();
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F);
+ fairySoul.render(context);
}
}
}
@@ -152,51 +165,37 @@ public class FairySouls {
private static void markClosestFairyFound() {
if (!fairySoulsLoaded.isDone()) return;
+
PlayerEntity player = MinecraftClient.getInstance().player;
if (player == null) {
LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because player is null");
return;
}
- fairySouls.get(Utils.getLocationRaw()).stream()
- .filter(FairySouls::isFairySoulMissing)
- .min(Comparator.comparingDouble(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos())))
- .filter(fairySoulPos -> fairySoulPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(fairySoulPos -> {
- initializeFoundFairiesForCurrentProfileAndLocation();
- foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).add(fairySoulPos);
- });
- }
- private static boolean isFairySoulMissing(BlockPos fairySoulPos) {
- Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile());
- if (foundFairiesForProfile == null) {
- return true;
- }
- Set<BlockPos> foundFairiesForProfileAndLocation = foundFairiesForProfile.get(Utils.getLocationRaw());
- if (foundFairiesForProfileAndLocation == null) {
- return true;
+ Map<BlockPos, ProfileAwareWaypoint> fairiesOnCurrentIsland = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesOnCurrentIsland == null) {
+ LOGGER.warn("[Skyblocker] Failed to mark closest fairy soul as found because there are no fairy souls loaded on the current island. NEU repo probably failed to load.");
+ return;
}
- return !foundFairiesForProfileAndLocation.contains(fairySoulPos);
+
+ fairiesOnCurrentIsland.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos())))
+ .filter(fairySoul -> fairySoul.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
public static void markAllFairiesOnCurrentIslandFound() {
- initializeFoundFairiesForCurrentProfileAndLocation();
- foundFairies.get(Utils.getProfile()).get(Utils.getLocationRaw()).addAll(fairySouls.get(Utils.getLocationRaw()));
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesForLocation != null) {
+ fairiesForLocation.values().forEach(ProfileAwareWaypoint::setFound);
+ }
}
public static void markAllFairiesOnCurrentIslandMissing() {
- Map<String, Set<BlockPos>> foundFairiesForProfile = foundFairies.get(Utils.getProfile());
- if (foundFairiesForProfile != null) {
- foundFairiesForProfile.remove(Utils.getLocationRaw());
+ Map<BlockPos, ProfileAwareWaypoint> fairiesForLocation = fairySouls.get(Utils.getLocationRaw());
+ if (fairiesForLocation != null) {
+ fairiesForLocation.values().forEach(ProfileAwareWaypoint::setMissing);
}
}
-
- private static void initializeFoundFairiesForCurrentProfileAndLocation() {
- initializeFoundFairiesForProfileAndLocation(Utils.getProfile(), Utils.getLocationRaw());
- }
-
- private static void initializeFoundFairiesForProfileAndLocation(String profile, String location) {
- foundFairies.computeIfAbsent(profile, profileKey -> new HashMap<>());
- foundFairies.get(profile).computeIfAbsent(location, locationKey -> new HashSet<>());
- }
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java
index e2962702..5b5f4715 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/diana/MythologicalRitual.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/MythologicalRitual.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock.diana;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.mojang.brigadier.Command;
import de.hysky.skyblocker.SkyblockerMod;
@@ -108,7 +108,7 @@ public class MythologicalRitual {
burrow.nextBurrowPlane[1] = Vec3d.of(pos).subtract(nextBurrowDirection).subtract(0, 50, 0);
burrow.nextBurrowPlane[2] = burrow.nextBurrowPlane[1].add(0, 100, 0);
burrow.nextBurrowPlane[3] = burrow.nextBurrowPlane[0].add(0, 100, 0);
- } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType())) {
+ } else if (ParticleTypes.DRIPPING_LAVA.equals(packet.getParameters().getType()) && packet.getCount() == 2) {
if (System.currentTimeMillis() > lastEchoTime + 10_000) {
return;
}
diff --git a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java
index aaf4d77c..952f2f59 100644
--- a/src/main/java/de/hysky/skyblocker/skyblock/spidersden/Relics.java
+++ b/src/main/java/de/hysky/skyblocker/skyblock/waypoint/Relics.java
@@ -1,4 +1,4 @@
-package de.hysky.skyblocker.skyblock.spidersden;
+package de.hysky.skyblocker.skyblock.waypoint;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -11,7 +11,8 @@ import de.hysky.skyblocker.config.SkyblockerConfigManager;
import de.hysky.skyblocker.utils.Constants;
import de.hysky.skyblocker.utils.PosUtils;
import de.hysky.skyblocker.utils.Utils;
-import de.hysky.skyblocker.utils.render.RenderHelper;
+import de.hysky.skyblocker.utils.waypoint.ProfileAwareWaypoint;
+import de.hysky.skyblocker.utils.waypoint.Waypoint;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
@@ -28,19 +29,24 @@ import net.minecraft.util.math.BlockPos;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
+import java.util.function.Supplier;
import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
public class Relics {
private static final Logger LOGGER = LoggerFactory.getLogger(Relics.class);
+ private static final Supplier<Waypoint.Type> TYPE_SUPPLIER = () -> SkyblockerConfigManager.get().general.waypoints.waypointType;
private static CompletableFuture<Void> relicsLoaded;
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private static int totalRelics = 0;
- private static final List<BlockPos> relics = new ArrayList<>();
- private static final Map<String, Set<BlockPos>> foundRelics = new HashMap<>();
+ private static final Map<BlockPos, ProfileAwareWaypoint> relics = new HashMap<>();
public static void init() {
ClientLifecycleEvents.CLIENT_STARTED.register(Relics::loadRelics);
@@ -59,7 +65,8 @@ public class Relics {
} else if (json.getKey().equals("locations")) {
for (JsonElement locationJson : json.getValue().getAsJsonArray().asList()) {
JsonObject posData = locationJson.getAsJsonObject();
- relics.add(new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt()));
+ BlockPos pos = new BlockPos(posData.get("x").getAsInt(), posData.get("y").getAsInt(), posData.get("z").getAsInt());
+ relics.put(pos, new ProfileAwareWaypoint(pos, TYPE_SUPPLIER, DyeColor.YELLOW.getColorComponents(), DyeColor.BROWN.getColorComponents()));
}
}
}
@@ -68,16 +75,14 @@ public class Relics {
LOGGER.error("[Skyblocker] Failed to load relics locations", e);
}
- try (BufferedReader reader = new BufferedReader(new FileReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) {
+ try (BufferedReader reader = Files.newBufferedReader(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) {
for (Map.Entry<String, JsonElement> profileJson : JsonParser.parseReader(reader).getAsJsonObject().asMap().entrySet()) {
- Set<BlockPos> foundRelicsForProfile = new HashSet<>();
for (JsonElement foundRelicsJson : profileJson.getValue().getAsJsonArray().asList()) {
- foundRelicsForProfile.add(PosUtils.parsePosString(foundRelicsJson.getAsString()));
+ relics.get(PosUtils.parsePosString(foundRelicsJson.getAsString())).setFound(profileJson.getKey());
}
- foundRelics.put(profileJson.getKey(), foundRelicsForProfile);
}
LOGGER.debug("[Skyblocker] Loaded found relics");
- } catch (FileNotFoundException ignored) {
+ } catch (NoSuchFileException ignored) {
} catch (IOException e) {
LOGGER.error("[Skyblocker] Failed to load found relics", e);
}
@@ -85,7 +90,15 @@ public class Relics {
}
private static void saveFoundRelics(MinecraftClient client) {
- try (BufferedWriter writer = new BufferedWriter(new FileWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json").toFile()))) {
+ Map<String, Set<BlockPos>> foundRelics = new HashMap<>();
+ for (ProfileAwareWaypoint relic : relics.values()) {
+ for (String profile : relic.foundProfiles) {
+ foundRelics.computeIfAbsent(profile, profile_ -> new HashSet<>());
+ foundRelics.get(profile).add(relic.pos);
+ }
+ }
+
+ try (BufferedWriter writer = Files.newBufferedWriter(SkyblockerMod.CONFIG_DIR.resolve("found_relics.json"))) {
JsonObject json = new JsonObject();
for (Map.Entry<String, Set<BlockPos>> foundRelicsForProfile : foundRelics.entrySet()) {
JsonArray foundRelicsJson = new JsonArray();
@@ -105,12 +118,12 @@ public class Relics {
dispatcher.register(literal(SkyblockerMod.NAMESPACE)
.then(literal("relics")
.then(literal("markAllFound").executes(context -> {
- Relics.markAllFound();
+ relics.values().forEach(ProfileAwareWaypoint::setFound);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllFound")));
return 1;
}))
.then(literal("markAllMissing").executes(context -> {
- Relics.markAllMissing();
+ relics.values().forEach(ProfileAwareWaypoint::setMissing);
context.getSource().sendFeedback(Constants.PREFIX.get().append(Text.translatable("skyblocker.relics.markAllMissing")));
return 1;
}))));
@@ -120,11 +133,10 @@ public class Relics {
SkyblockerConfig.Relics config = SkyblockerConfigManager.get().locations.spidersDen.relics;
if (config.enableRelicsHelper && relicsLoaded.isDone() && Utils.getLocationRaw().equals("combat_1")) {
- for (BlockPos fairySoulPos : relics) {
- boolean isRelicMissing = isRelicMissing(fairySoulPos);
+ for (ProfileAwareWaypoint relic : relics.values()) {
+ boolean isRelicMissing = relic.shouldRender();
if (!isRelicMissing && !config.highlightFoundRelics) continue;
- float[] colorComponents = isRelicMissing ? DyeColor.YELLOW.getColorComponents() : DyeColor.BROWN.getColorComponents();
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, fairySoulPos, colorComponents, 0.5F);
+ relic.render(context);
}
}
}
@@ -143,30 +155,10 @@ public class Relics {
LOGGER.warn("[Skyblocker] Failed to mark closest relic as found because player is null");
return;
}
- relics.stream()
- .filter(Relics::isRelicMissing)
- .min(Comparator.comparingDouble(relicPos -> relicPos.getSquaredDistance(player.getPos())))
- .filter(relicPos -> relicPos.getSquaredDistance(player.getPos()) <= 16)
- .ifPresent(relicPos -> {
- foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>());
- foundRelics.get(Utils.getProfile()).add(relicPos);
- });
- }
-
- private static boolean isRelicMissing(BlockPos relicPos) {
- Set<BlockPos> foundRelicsForProfile = foundRelics.get(Utils.getProfile());
- return foundRelicsForProfile == null || !foundRelicsForProfile.contains(relicPos);
- }
-
- private static void markAllFound() {
- foundRelics.computeIfAbsent(Utils.getProfile(), profileKey -> new HashSet<>());
- foundRelics.get(Utils.getProfile()).addAll(relics);
- }
-
- private static void markAllMissing() {
- Set<BlockPos> foundRelicsForProfile = foundRelics.get(Utils.getProfile());
- if (foundRelicsForProfile != null) {
- foundRelicsForProfile.clear();
- }
+ relics.values().stream()
+ .filter(Waypoint::shouldRender)
+ .min(Comparator.comparingDouble(relic -> relic.pos.getSquaredDistance(player.getPos())))
+ .filter(relic -> relic.pos.getSquaredDistance(player.getPos()) <= 16)
+ .ifPresent(Waypoint::setFound);
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
index c0648eba..0121f8ad 100644
--- a/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/ApiUtils.java
@@ -21,33 +21,33 @@ public class ApiUtils {
* Do not iterate over this map, it will be accessed and modified by multiple threads.
*/
private static final Object2ObjectOpenHashMap<String, String> NAME_2_UUID_CACHE = new Object2ObjectOpenHashMap<>();
-
+
public static void init() {
//Clear cache every 20 minutes
Scheduler.INSTANCE.scheduleCyclic(NAME_2_UUID_CACHE::clear, 24_000, true);
}
-
+
/**
* Multithreading is to be handled by the method caller
*/
public static String name2Uuid(String name) {
Session session = MinecraftClient.getInstance().getSession();
-
+
if (session.getUsername().equals(name)) return UndashedUuid.toString(session.getUuidOrNull());
if (NAME_2_UUID_CACHE.containsKey(name)) return NAME_2_UUID_CACHE.get(name);
-
+
try (ApiResponse response = Http.sendName2UuidRequest(name)) {
if (response.ok()) {
String uuid = JsonParser.parseString(response.content()).getAsJsonObject().get("id").getAsString();
-
+
NAME_2_UUID_CACHE.put(name, uuid);
-
+
return uuid;
}
} catch (Exception e) {
LOGGER.error("[Skyblocker] Name to uuid lookup failed! Name: {}", name, e);
}
-
+
return "";
}
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/Constants.java b/src/main/java/de/hysky/skyblocker/utils/Constants.java
index 94eacf49..134b7888 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Constants.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Constants.java
@@ -14,7 +14,7 @@ import net.minecraft.util.Formatting;
* Holds generic static constants
*/
public interface Constants {
- String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u12DE";
+ String LEVEL_EMBLEMS = "\u2E15\u273F\u2741\u2E19\u03B1\u270E\u2615\u2616\u2663\u213B\u2694\u27B6\u26A1\u2604\u269A\u2693\u2620\u269B\u2666\u2660\u2764\u2727\u238A\u1360\u262C\u269D\u29C9\uA214\u32D6\u2E0E\u26A0\uA541\u3020\u30C4\u2948\u2622\u2623\u273E\u269C\u0BD0\u0A6D\u2742\u16C3\u3023\u10F6\u0444\u266A\u266B\u04C3\u26C1\u26C3\u16DD\uA03E\u1C6A\u03A3\u09EB\u2603\u2654\u26C2\u0FC7\uA56A\u12DE";
IntFunction<UnaryOperator<Style>> WITH_COLOR = color -> style -> style.withColor(color);
Supplier<MutableText> PREFIX = () -> Text.empty()
.append(Text.literal("[").formatted(Formatting.GRAY))
diff --git a/src/main/java/de/hysky/skyblocker/utils/Http.java b/src/main/java/de/hysky/skyblocker/utils/Http.java
index 573c3458..eced3c08 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Http.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Http.java
@@ -26,17 +26,17 @@ import net.minecraft.SharedConstants;
*/
public class Http {
private static final String NAME_2_UUID = "https://api.minecraftservices.com/minecraft/profile/lookup/name/";
- private static final String HYPIXEL_PROXY = "https://hysky.de/api/hypixel/";
+ private static final String HYPIXEL_PROXY = "https://hysky.de/api/hypixel/v2/";
private static final String USER_AGENT = "Skyblocker/" + SkyblockerMod.VERSION + " (" + SharedConstants.getGameVersion().getName() + ")";
private static final HttpClient HTTP_CLIENT = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(10))
.followRedirects(Redirect.NORMAL)
.build();
-
+
public static String sendGetRequest(String url) throws IOException, InterruptedException {
return sendCacheableGetRequest(url).content();
}
-
+
private static ApiResponse sendCacheableGetRequest(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.GET()
@@ -46,16 +46,16 @@ public class Http {
.version(Version.HTTP_2)
.uri(URI.create(url))
.build();
-
+
HttpResponse<InputStream> response = HTTP_CLIENT.send(request, BodyHandlers.ofInputStream());
InputStream decodedInputStream = getDecodedInputStream(response);
-
+
String body = new String(decodedInputStream.readAllBytes());
HttpHeaders headers = response.headers();
-
+
return new ApiResponse(body, response.statusCode(), getCacheStatus(headers), getAge(headers));
}
-
+
public static HttpHeaders sendHeadRequest(String url) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.method("HEAD", BodyPublishers.noBody())
@@ -63,27 +63,29 @@ public class Http {
.version(Version.HTTP_2)
.uri(URI.create(url))
.build();
-
- HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
+
+ HttpResponse<Void> response = HTTP_CLIENT.send(request, BodyHandlers.discarding());
return response.headers();
}
-
+
public static ApiResponse sendName2UuidRequest(String name) throws IOException, InterruptedException {
return sendCacheableGetRequest(NAME_2_UUID + name);
}
-
+
/**
* @param endpoint the endpoint - do not include any leading or trailing slashes
* @param query the query string - use empty string if n/a
* @return the requested data with zero pre-processing applied
+ *
+ * @implNote the {@code v2} prefix is automatically added
*/
public static ApiResponse sendHypixelRequest(String endpoint, @NotNull String query) throws IOException, InterruptedException {
return sendCacheableGetRequest(HYPIXEL_PROXY + endpoint + query);
}
-
+
private static InputStream getDecodedInputStream(HttpResponse<InputStream> response) {
String encoding = getContentEncoding(response.headers());
-
+
try {
switch (encoding) {
case "":
@@ -99,19 +101,19 @@ public class Http {
throw new UncheckedIOException(e);
}
}
-
+
private static String getContentEncoding(HttpHeaders headers) {
return headers.firstValue("Content-Encoding").orElse("");
}
-
+
public static String getEtag(HttpHeaders headers) {
return headers.firstValue("Etag").orElse("");
}
-
+
public static String getLastModified(HttpHeaders headers) {
return headers.firstValue("Last-Modified").orElse("");
}
-
+
/**
* Returns the cache status of the resource
*
@@ -120,18 +122,18 @@ public class Http {
private static String getCacheStatus(HttpHeaders headers) {
return headers.firstValue("CF-Cache-Status").orElse("UNKNOWN");
}
-
+
private static int getAge(HttpHeaders headers) {
return Integer.parseInt(headers.firstValue("Age").orElse("-1"));
}
-
+
//TODO If ever needed, we could just replace cache status with the response headers and go from there
public record ApiResponse(String content, int statusCode, String cacheStatus, int age) implements AutoCloseable {
-
+
public boolean ok() {
return statusCode == 200;
}
-
+
public boolean cached() {
return cacheStatus.equals("HIT");
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
index 6d78b3f3..870e94da 100644
--- a/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
+++ b/src/main/java/de/hysky/skyblocker/utils/NEURepoManager.java
@@ -14,10 +14,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
+import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
/**
* Initializes the NEU repo, which contains item metadata and fairy souls location data. Clones the repo if it does not exist and checks for updates. Use {@link #runAsyncAfterLoad(Runnable)} to run code after the repo is initialized.
@@ -74,8 +76,7 @@ public class NEURepoManager {
CompletableFuture.runAsync(() -> {
try {
ItemRepository.setFilesImported(false);
- File dir = NEURepoManager.LOCAL_REPO_DIR.toFile();
- recursiveDelete(dir);
+ recursiveDelete(NEURepoManager.LOCAL_REPO_DIR);
} catch (Exception ex) {
if (MinecraftClient.getInstance().player != null)
MinecraftClient.getInstance().player.sendMessage(Constants.PREFIX.get().append(Text.translatable("skyblocker.updaterepository.failed")), false);
@@ -86,14 +87,18 @@ public class NEURepoManager {
}
@SuppressWarnings("ResultOfMethodCallIgnored")
- private static void recursiveDelete(File dir) {
- File[] children;
- if (dir.isDirectory() && !Files.isSymbolicLink(dir.toPath()) && (children = dir.listFiles()) != null) {
- for (File child : children) {
- recursiveDelete(child);
- }
+ private static void recursiveDelete(Path dir) throws IOException {
+ if (Files.isDirectory(dir) && !Files.isSymbolicLink(dir)) {
+ Files.list(dir).forEach(child -> {
+ try {
+ recursiveDelete(child);
+ } catch (Exception e) {
+ LOGGER.error("[Skyblocker] Encountered an exception while deleting a file! Path: {}", child.toAbsolutePath(), e);
+ }
+ });
}
- dir.delete();
+
+ Files.delete(dir);
}
/**
diff --git a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
index 0a42c6ae..2edd61f1 100644
--- a/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/SlayerUtils.java
@@ -42,13 +42,13 @@ public class SlayerUtils {
try {
for (int i = 0; i < Utils.STRING_SCOREBOARD.size(); i++) {
String line = Utils.STRING_SCOREBOARD.get(i);
-
+
if (line.contains("Slay the boss!")) return true;
}
} catch (NullPointerException e) {
LOGGER.error("[Skyblocker] Error while checking if player is in slayer", e);
}
-
+
return false;
}
} \ No newline at end of file
diff --git a/src/main/java/de/hysky/skyblocker/utils/Utils.java b/src/main/java/de/hysky/skyblocker/utils/Utils.java
index 71e08865..02b1637b 100644
--- a/src/main/java/de/hysky/skyblocker/utils/Utils.java
+++ b/src/main/java/de/hysky/skyblocker/utils/Utils.java
@@ -363,7 +363,7 @@ public class Utils {
if (isOnSkyblock && message.startsWith("Profile ID: ")) {
profileId = message.replace("Profile ID: ", "");
-
+
MuseumItemCache.tick(profileId);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
index 7892445e..2c75ef0a 100644
--- a/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
+++ b/src/main/java/de/hysky/skyblocker/utils/chat/ChatMessageListener.java
@@ -9,7 +9,6 @@ import de.hysky.skyblocker.skyblock.dungeon.ThreeWeirdos;
import de.hysky.skyblocker.skyblock.dungeon.Trivia;
import de.hysky.skyblocker.skyblock.dwarven.Fetchur;
import de.hysky.skyblocker.skyblock.dwarven.Puzzler;
-import de.hysky.skyblocker.skyblock.filters.*;
import net.fabricmc.fabric.api.client.message.v1.ClientReceiveMessageEvents;
import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory;
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
index 064b564c..43d595a5 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/RenderHelper.java
@@ -1,11 +1,16 @@
package de.hysky.skyblocker.utils.render;
import com.mojang.blaze3d.systems.RenderSystem;
+import com.mojang.logging.LogUtils;
+
+import de.hysky.skyblocker.SkyblockerMod;
import de.hysky.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
import de.hysky.skyblocker.utils.render.culling.OcclusionCulling;
import de.hysky.skyblocker.utils.render.title.Title;
import de.hysky.skyblocker.utils.render.title.TitleContainer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.fabricmc.fabric.api.event.Event;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.render.*;
@@ -14,65 +19,63 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.OrderedText;
import net.minecraft.text.Text;
+import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.lwjgl.opengl.GL11;
+import org.slf4j.Logger;
public class RenderHelper {
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final Identifier TRANSLUCENT_DRAW = new Identifier(SkyblockerMod.NAMESPACE, "translucent_draw");
+ private static final MethodHandle SCHEDULE_DEFERRED_RENDER_TASK = getDeferredRenderTaskHandle();
private static final Vec3d ONE = new Vec3d(1, 1, 1);
private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
private static final MinecraftClient client = MinecraftClient.getInstance();
- public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- renderFilledThroughWalls(context, pos, colorComponents, alpha);
- renderBeaconBeam(context, pos, colorComponents);
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.addPhaseOrdering(Event.DEFAULT_PHASE, TRANSLUCENT_DRAW);
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(TRANSLUCENT_DRAW, RenderHelper::drawTranslucents);
}
- public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true);
- }
+ public static void renderFilledWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) {
+ renderFilled(context, pos, colorComponents, alpha, throughWalls);
+ renderBeaconBeam(context, pos, colorComponents);
}
- public static void renderFilledIfVisible(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
- renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false);
+ public static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha, boolean throughWalls) {
+ if (throughWalls) {
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, true);
+ }
+ } else {
+ if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ renderFilled(context, Vec3d.of(pos), ONE, colorComponents, alpha, false);
+ }
}
}
-
+
private static void renderFilled(WorldRenderContext context, Vec3d pos, Vec3d dimensions, float[] colorComponents, float alpha, boolean throughWalls) {
MatrixStack matrices = context.matrixStack();
Vec3d camera = context.camera().getPos();
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
-
+
matrices.push();
matrices.translate(-camera.x, -camera.y, -camera.z);
-
- RenderSystem.setShader(GameRenderer::getPositionColorProgram);
- RenderSystem.setShaderColor(1f, 1f, 1f, 1f);
- RenderSystem.polygonOffset(-1f, -10f);
- RenderSystem.enablePolygonOffset();
- RenderSystem.enableBlend();
- RenderSystem.defaultBlendFunc();
- RenderSystem.enableDepthTest();
- RenderSystem.depthFunc(throughWalls ? GL11.GL_ALWAYS : GL11.GL_LEQUAL);
- RenderSystem.disableCull();
-
- buffer.begin(DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR);
+
+ VertexConsumerProvider consumers = context.consumers();
+ VertexConsumer buffer = consumers.getBuffer(throughWalls ? SkyblockerRenderLayers.FILLED_THROUGH_WALLS : SkyblockerRenderLayers.FILLED);
+
WorldRenderer.renderFilledBox(matrices, buffer, pos.x, pos.y, pos.z, pos.x + dimensions.x, pos.y + dimensions.y, pos.z + dimensions.z, colorComponents[0], colorComponents[1], colorComponents[2], alpha);
- tessellator.draw();
-
+
matrices.pop();
- RenderSystem.polygonOffset(0f, 0f);
- RenderSystem.disablePolygonOffset();
- RenderSystem.disableBlend();
- RenderSystem.disableDepthTest();
- RenderSystem.depthFunc(GL11.GL_LEQUAL);
- RenderSystem.enableCull();
}
private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
@@ -83,13 +86,8 @@ public class RenderHelper {
matrices.push();
matrices.translate(pos.getX() - camera.getX(), pos.getY() - camera.getY(), pos.getZ() - camera.getZ());
- Tessellator tessellator = RenderSystem.renderThreadTesselator();
- BufferBuilder buffer = tessellator.getBuffer();
- VertexConsumerProvider.Immediate consumer = VertexConsumerProvider.immediate(buffer);
-
- BeaconBlockEntityRendererInvoker.renderBeam(matrices, consumer, context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
+ BeaconBlockEntityRendererInvoker.renderBeam(matrices, context.consumers(), context.tickDelta(), context.world().getTime(), 0, MAX_OVERWORLD_BUILD_HEIGHT, colorComponents);
- consumer.draw();
matrices.pop();
}
}
@@ -259,6 +257,28 @@ public class RenderHelper {
}
/**
+ * This is called after all {@link WorldRenderEvents#AFTER_TRANSLUCENT} listeners have been called so that we can draw all remaining render layers.
+ */
+ private static void drawTranslucents(WorldRenderContext context) {
+ //Draw all render layers that haven't been drawn yet - drawing a specific layer does nothing and idk why
+ ((VertexConsumerProvider.Immediate) context.consumers()).draw();
+ }
+
+ public static void runOnRenderThread(Runnable runnable) {
+ if (RenderSystem.isOnRenderThread()) {
+ runnable.run();
+ } else if (SCHEDULE_DEFERRED_RENDER_TASK != null) { //Sodium
+ try {
+ SCHEDULE_DEFERRED_RENDER_TASK.invokeExact(runnable);
+ } catch (Throwable t) {
+ LOGGER.error("[Skyblocker] Failed to schedule a render task!", t);
+ }
+ } else { //Vanilla
+ RenderSystem.recordRenderCall(runnable::run);
+ }
+ }
+
+ /**
* Adds the title to {@link TitleContainer} and {@link #playNotificationSound() plays the notification sound} if the title is not in the {@link TitleContainer} already.
* No checking needs to be done on whether the title is in the {@link TitleContainer} already by the caller.
*
@@ -284,12 +304,26 @@ public class RenderHelper {
}
private static void playNotificationSound() {
- if (MinecraftClient.getInstance().player != null) {
- MinecraftClient.getInstance().player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
+ if (client.player != null) {
+ client.player.playSound(SoundEvents.ENTITY_EXPERIENCE_ORB_PICKUP, 100f, 0.1f);
}
}
public static boolean pointIsInArea(double x, double y, double x1, double y1, double x2, double y2) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
+
+ // TODO Get rid of reflection once the new Sodium is released
+ private static MethodHandle getDeferredRenderTaskHandle() {
+ try {
+ Class<?> deferredTaskClass = Class.forName("me.jellysquid.mods.sodium.client.render.util.DeferredRenderTask");
+
+ MethodHandles.Lookup lookup = MethodHandles.publicLookup();
+ MethodType mt = MethodType.methodType(void.class, Runnable.class);
+
+ return lookup.findStatic(deferredTaskClass, "schedule", mt);
+ } catch (Throwable ignored) {}
+
+ return null;
+ }
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
new file mode 100644
index 00000000..ee113cc4
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/render/SkyblockerRenderLayers.java
@@ -0,0 +1,36 @@
+package de.hysky.skyblocker.utils.render;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+
+import net.minecraft.client.render.RenderLayer;
+import net.minecraft.client.render.RenderLayer.MultiPhase;
+import net.minecraft.client.render.RenderLayer.MultiPhaseParameters;
+import net.minecraft.client.render.RenderPhase;
+import net.minecraft.client.render.RenderPhase.Cull;
+import net.minecraft.client.render.RenderPhase.DepthTest;
+import net.minecraft.client.render.RenderPhase.Transparency;
+import net.minecraft.client.render.VertexFormat.DrawMode;
+import net.minecraft.client.render.VertexFormats;
+
+public class SkyblockerRenderLayers {
+ private static final Transparency DEFAULT_TRANSPARENCY = new Transparency("default_transparency", () -> {
+ RenderSystem.enableBlend();
+ RenderSystem.defaultBlendFunc();
+ }, RenderSystem::disableBlend);
+
+ public static final MultiPhase FILLED = RenderLayer.of("filled", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.LEQUAL_DEPTH_TEST)
+ .build(false));
+
+ public static final MultiPhase FILLED_THROUGH_WALLS = RenderLayer.of("filled_through_walls", VertexFormats.POSITION_COLOR, DrawMode.TRIANGLE_STRIP, RenderLayer.CUTOUT_BUFFER_SIZE, false, true, MultiPhaseParameters.builder()
+ .program(RenderPhase.COLOR_PROGRAM)
+ .cull(Cull.DISABLE_CULLING)
+ .layering(RenderPhase.POLYGON_OFFSET_LAYERING)
+ .transparency(DEFAULT_TRANSPARENCY)
+ .depthTest(DepthTest.ALWAYS_DEPTH_TEST)
+ .build(false));
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
index 19d41c91..cc80f74c 100644
--- a/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
+++ b/src/main/java/de/hysky/skyblocker/utils/render/title/TitleContainerConfigScreen.java
@@ -27,7 +27,7 @@ public class TitleContainerConfigScreen extends Screen {
private float hudY = SkyblockerConfigManager.get().general.titleContainer.y;
private final Screen parent;
private boolean changedScale;
-
+
protected TitleContainerConfigScreen() {
this(null);
}
@@ -173,18 +173,18 @@ public class TitleContainerConfigScreen extends Screen {
public void close() {
SkyblockerConfigManager.get().general.titleContainer.x = (int) hudX;
SkyblockerConfigManager.get().general.titleContainer.y = (int) hudY;
-
+
//TODO Come up with a better, less hacky solution for this in the future (:
if (parent instanceof YACLScreen yaclScreen) {
ConfigCategory category = yaclScreen.config.categories().stream().filter(cat -> cat.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.category.general"))).findFirst().orElseThrow();
OptionGroup group = category.groups().stream().filter(grp -> grp.name().getString().equals(I18n.translate("text.autoconfig.skyblocker.option.general.titleContainer"))).findFirst().orElseThrow();
-
+
Option<?> scaleOpt = group.options().get(0);
-
+
// Refresh the value in the config with the bound value
if (changedScale) scaleOpt.forgetPendingValue();
}
-
+
SkyblockerConfigManager.save();
this.client.setScreen(parent);
}
diff --git a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
index b254f524..139ac05e 100644
--- a/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
+++ b/src/main/java/de/hysky/skyblocker/utils/scheduler/Scheduler.java
@@ -28,14 +28,14 @@ public class Scheduler {
protected Scheduler() {
}
-
+
/**
* @see #schedule(Runnable, int, boolean)
*/
public void schedule(Runnable task, int delay) {
schedule(task, delay, false);
}
-
+
/**
* @see #scheduleCyclic(Runnable, int, boolean)
*/
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java
new file mode 100644
index 00000000..7aa99d14
--- /dev/null
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypoint.java
@@ -0,0 +1,44 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import de.hysky.skyblocker.utils.Utils;
+import net.minecraft.util.math.BlockPos;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+
+public class ProfileAwareWaypoint extends Waypoint {
+ public final Set<String> foundProfiles = new HashSet<>();
+ private final float[] missingColor;
+ private final float[] foundColor;
+
+ public ProfileAwareWaypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] missingColor, float[] foundColor) {
+ super(pos, typeSupplier, null);
+ this.missingColor = missingColor;
+ this.foundColor = foundColor;
+ }
+
+ @Override
+ public boolean shouldRender() {
+ return !foundProfiles.contains(Utils.getProfile());
+ }
+
+ @Override
+ public void setFound() {
+ foundProfiles.add(Utils.getProfile());
+ }
+
+ public void setFound(String profile) {
+ foundProfiles.add(profile);
+ }
+
+ @Override
+ public void setMissing() {
+ foundProfiles.remove(Utils.getProfile());
+ }
+
+ @Override
+ protected float[] getColorComponents() {
+ return foundProfiles.contains(Utils.getProfile()) ? foundColor : missingColor;
+ }
+}
diff --git a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
index e7858f05..eb30cf8d 100644
--- a/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
+++ b/src/main/java/de/hysky/skyblocker/utils/waypoint/Waypoint.java
@@ -11,30 +11,30 @@ public class Waypoint {
protected static final float DEFAULT_HIGHLIGHT_ALPHA = 0.5f;
protected static final float DEFAULT_LINE_WIDTH = 5f;
public final BlockPos pos;
- private final Box box;
- private final Supplier<Type> typeSupplier;
- private final float[] colorComponents;
- private final float alpha;
- private final float lineWidth;
- private final boolean throughWalls;
+ final Box box;
+ final Supplier<Type> typeSupplier;
+ final float[] colorComponents;
+ final float alpha;
+ final float lineWidth;
+ final boolean throughWalls;
private boolean shouldRender;
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents) {
- this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA);
+ this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH);
}
protected Waypoint(BlockPos pos, Type type, float[] colorComponents, float alpha) {
- this(pos, () -> type, colorComponents, alpha);
- }
-
- protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha) {
- this(pos, typeSupplier, colorComponents, alpha, DEFAULT_LINE_WIDTH);
+ this(pos, () -> type, colorComponents, alpha, DEFAULT_LINE_WIDTH);
}
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth) {
this(pos, typeSupplier, colorComponents, alpha, lineWidth, true);
}
+ public Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, boolean throughWalls) {
+ this(pos, typeSupplier, colorComponents, DEFAULT_HIGHLIGHT_ALPHA, DEFAULT_LINE_WIDTH, throughWalls);
+ }
+
protected Waypoint(BlockPos pos, Supplier<Type> typeSupplier, float[] colorComponents, float alpha, float lineWidth, boolean throughWalls) {
this(pos, typeSupplier, colorComponents, alpha, lineWidth, throughWalls, true);
}
@@ -62,19 +62,25 @@ public class Waypoint {
this.shouldRender = true;
}
+ protected float[] getColorComponents() {
+ return colorComponents;
+ }
+
public void render(WorldRenderContext context) {
switch (typeSupplier.get()) {
- case WAYPOINT -> RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ case WAYPOINT -> RenderHelper.renderFilledWithBeaconBeam(context, pos, getColorComponents(), alpha, throughWalls);
case OUTLINED_WAYPOINT -> {
- RenderHelper.renderFilledThroughWallsWithBeaconBeam(context, pos, colorComponents, alpha);
+ float[] colorComponents = getColorComponents();
+ RenderHelper.renderFilledWithBeaconBeam(context, pos, colorComponents, alpha, throughWalls);
RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
}
- case HIGHLIGHT -> RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ case HIGHLIGHT -> RenderHelper.renderFilled(context, pos, getColorComponents(), alpha, throughWalls);
case OUTLINED_HIGHLIGHT -> {
- RenderHelper.renderFilledThroughWalls(context, pos, colorComponents, alpha);
+ float[] colorComponents = getColorComponents();
+ RenderHelper.renderFilled(context, pos, colorComponents, alpha, throughWalls);
RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
}
- case OUTLINE -> RenderHelper.renderOutline(context, box, colorComponents, lineWidth, throughWalls);
+ case OUTLINE -> RenderHelper.renderOutline(context, box, getColorComponents(), lineWidth, throughWalls);
}
}
diff --git a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
index a0a97c67..0f22f597 100644
--- a/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
+++ b/src/main/resources/assets/skyblocker/dungeons/secretlocations.json
@@ -2173,7 +2173,7 @@
},
{
"secretName":"3 - Lever 2",
- "category":"Lever",
+ "category":"lever",
"x":31,
"y":53,
"z":24
@@ -2375,7 +2375,7 @@
},
{
"secretName":"2 - Item",
- "category":"Item",
+ "category":"item",
"x":27,
"y":56,
"z":19
@@ -3936,7 +3936,7 @@
},
{
"secretName":"4/5/6 - Entrance 3",
- "category":"",
+ "category":"entrance",
"x":31,
"y":142,
"z":39
diff --git a/src/main/resources/assets/skyblocker/lang/en_ca.json b/src/main/resources/assets/skyblocker/lang/en_ca.json
index 5ecbd676..883de5dc 100644
--- a/src/main/resources/assets/skyblocker/lang/en_ca.json
+++ b/src/main/resources/assets/skyblocker/lang/en_ca.json
@@ -2,8 +2,8 @@
"text.autoconfig.skyblocker.option.general.bars": "Health, Mana, Defence & XP Bars",
"text.autoconfig.skyblocker.option.locations.dungeons.croesusHelper.@Tooltip": "Grey out chests that have already been opened.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Colour",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Colour",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Send the livid colour in the chat during the Livid boss fight.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Enable Livid Colour",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Send the livid colour in the chat during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Livid Colour Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Text which will be sent in the chat during the Livid boss fight. The string \"[color]\" will be replaced with the livid colour.",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Solve Select Coloured",
diff --git a/src/main/resources/assets/skyblocker/lang/en_us.json b/src/main/resources/assets/skyblocker/lang/en_us.json
index 31e7bb9c..b0d70a2d 100644
--- a/src/main/resources/assets/skyblocker/lang/en_us.json
+++ b/src/main/resources/assets/skyblocker/lang/en_us.json
@@ -50,6 +50,11 @@
"text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts": "Enable Command Argument Shortcuts",
"text.autoconfig.skyblocker.option.general.shortcuts.enableCommandArgShortcuts.@Tooltip": "Shortcuts that replace one or more word(s)/argument(s) of a command which has multiple words/arguments. Edit shortcuts with \"/skyblocker shortcuts\". Shortcuts must be enabled for this to take effect.",
"text.autoconfig.skyblocker.option.general.shortcuts.config": "Shortcuts Config...",
+ "text.autoconfig.skyblocker.option.general.waypoints": "Waypoints",
+ "text.autoconfig.skyblocker.option.general.waypoints.enableWaypoints": "Enable Waypoints",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType": "Waypoint Type",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and a beacon beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Only displays an outline.",
+ "text.autoconfig.skyblocker.option.general.waypoints.waypointType.generalNote": "\n\n\nThis option does not apply to all waypoints. Some waypoints such as secret waypoints have their own waypoint type option.",
"text.autoconfig.skyblocker.option.general.quiverWarning": "Quiver Warning",
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarning": "Enable Quiver Warning",
"text.autoconfig.skyblocker.option.general.quiverWarning.enableQuiverWarningInDungeons": "Enable Quiver Warning In Dungeons",
@@ -76,7 +81,9 @@
"text.autoconfig.skyblocker.option.general.itemTooltip.avg.BOTH": "Both",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableLowestBIN": "Enable Lowest BIN Price",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableBazaarPrice": "Enable Bazaar buy/sell Price",
- "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumDate": "Enable Museum & Date",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableObtainedDate": "Enable Obtained Date",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo": "Enable Museum Info",
+ "text.autoconfig.skyblocker.option.general.itemTooltip.enableMuseumInfo.@Tooltip": "If this item is donatable to the museum, then the item's category in the musuem is displayed. It also displays a marker indicating whether you've donated that item to your musuem or not (freebies not yet supported).\n\nMake sure to enable your Museum API for accurate information!",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticTooltip": "Enable Exotic Tooltip",
"text.autoconfig.skyblocker.option.general.itemTooltip.enableExoticTooltip.@Tooltip": "Displays the type of exotic below the item's name if an armor piece is exotic.",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay": "Item Info Display",
@@ -84,6 +91,8 @@
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.attributeShardInfo.@Tooltip": "Displays the attribute's level as the stack count and the initials of the attribute's name.",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds": "Item Rarity Backgrounds",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgrounds.@Tooltip": "Displays a colored background behind an item, the color represents the item's rarity.",
+ "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle": "Item Rarity Background Style",
+ "text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundStyle.@Tooltip": "Choose between a circular or a square background style!",
"text.autoconfig.skyblocker.option.general.itemInfoDisplay.itemRarityBackgroundsOpacity": "Item Rarity Backgrounds Opacity",
"text.autoconfig.skyblocker.option.general.wikiLookup": "Wiki Lookup",
"text.autoconfig.skyblocker.option.general.wikiLookup.enableWikiLookup": "Enable Wiki Lookup",
@@ -152,8 +161,6 @@
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSecretWaypoints": "Enable Dungeon Secret Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints": "Do Not Initialize Secret Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.noInitSecretWaypoints.@Tooltip": "This option can save around 20 MB of ram if enabled, but Secret Waypoint will require a restart after turning off this option to work.",
- "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType": "Waypoint Type",
- "text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.waypointType.@Tooltip": "Waypoint: Displays a highlight and beam.\n\nOutlined Waypoint: Displays both a waypoint and an outline.\n\nHighlight: Only displays a highlight.\n\nOutlined Highlight: Displays both a highlight and an outline.\n\nOutline: Outlines the secret in a box.",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.showSecretText": "Show Secret Text",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableEntranceWaypoints" : "Enable Entrance Waypoints",
"text.autoconfig.skyblocker.option.locations.dungeons.secretWaypoints.enableSuperboomWaypoints" : "Enable Superboom Waypoints",
@@ -188,6 +195,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Enable Map",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScreen": "Dungeon Map Placement Config...",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Map Scaling",
+ "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker": "Player Secrets Tracker",
+ "text.autoconfig.skyblocker.option.locations.dungeons.playerSecretsTracker.@Tooltip": "Tracks the amount of secrets people in your dungeon run are doing.",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Starred Mob Glow",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow.@Tooltip": "Applies the glowing effect to starred mobs that are visible.",
"text.autoconfig.skyblocker.option.locations.dungeons.solveThreeWeirdos": "Solve Three Weirdos Puzzle",
@@ -199,8 +208,10 @@
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe": "Solve Tic Tac Toe Puzzle",
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe.@Tooltip": "Puts a red box around the next best move for you to make!",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Livid Color",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Enable Livid Color",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Send the livid color in the chat during the Livid boss fight.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow": "Enable Livid Color Glow",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorGlow.@Tooltip": "Applies the glowing effect to the correct Livid in F5/M5.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Enable Livid Color Text",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Send the livid color in the chat during the Livid boss fight.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Livid Color Text",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Text which will be sent in the chat during the Livid boss fight. The string \"[color]\" will be replaced with the livid color.",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Terminal Solvers",
@@ -222,6 +233,8 @@
"text.autoconfig.skyblocker.option.locations.rift": "The Rift",
"text.autoconfig.skyblocker.option.locations.rift.mirrorverseWaypoints": "Enable Mirrorverse Waypoints",
+ "text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow": "Blobbercyst Glow",
+ "text.autoconfig.skyblocker.option.locations.rift.blobbercystGlow.@Tooltip": "Applies the glowing effect to the Blobbercysts from the BACTE fight.",
"text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints": "Enable Enigma Soul Waypoints",
"text.autoconfig.skyblocker.option.locations.rift.enigmaSoulWaypoints.@Tooltip": "Note: Many enigma souls have a small task you must complete in order to get it, so its recommended to also watch a YouTube video when finding them.",
"text.autoconfig.skyblocker.option.locations.rift.highlightFoundEnigmaSouls": "Highlight Found Enigma Souls",
@@ -234,7 +247,8 @@
"text.autoconfig.skyblocker.option.messages.chatFilterResult.ACTION_BAR": "Move to action bar",
"text.autoconfig.skyblocker.option.messages.hideAbility": "Hide Ability Cooldown",
"text.autoconfig.skyblocker.option.messages.hideHeal": "Hide Heal Messages",
- "text.autoconfig.skyblocker.option.messages.hideAOTE": "Hide AOTE Messages",
+ "text.autoconfig.skyblocker.option.messages.hideAOTE": "Hide Teleport Ability Messages",
+ "text.autoconfig.skyblocker.option.messages.hideAOTE.@Tooltip": "Hides those pesky \"There are blocks in the way!\" messages.",
"text.autoconfig.skyblocker.option.messages.hideImplosion": "Hide Implosion Message",
"text.autoconfig.skyblocker.option.messages.hideMoltenWave": "Hide Molten Wave Message",
"text.autoconfig.skyblocker.option.messages.hideAds": "Hide Ads From Public Chat",
@@ -315,7 +329,7 @@
"skyblocker.shortcuts.deleteQuestion": "Are you sure you want to remove this shortcut?",
"skyblocker.shortcuts.deleteWarning": "Shortcut '%s' will be lost forever! (A long time!)",
"skyblocker.shortcuts.new": "New Shortcut",
- "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after a restart of the game.",
+ "skyblocker.shortcuts.commandSuggestionTooltip": "Due to limitations of Minecraft, command suggestions will only work after joining a new world.",
"skyblocker.customItemNames.removed": "§fRemoved this item's custom name.",
"skyblocker.customItemNames.neverHad": "§fThis item doesn't have a custom name set, but why not add one? ;)",
diff --git a/src/main/resources/assets/skyblocker/lang/fr_fr.json b/src/main/resources/assets/skyblocker/lang/fr_fr.json
index 207852ac..a08371b3 100644
--- a/src/main/resources/assets/skyblocker/lang/fr_fr.json
+++ b/src/main/resources/assets/skyblocker/lang/fr_fr.json
@@ -67,8 +67,8 @@
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Taille de la Carte",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Texte qui sera envoyé dans le chat lors du boss Livid. Le string \"[color]\" sera remplacé par la couleur Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Couleur Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Activer la Couleur Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Envoyer la Couler Livid dans le chat durant le boss Livid.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Activer la Couleur Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Envoyer la Couler Livid dans le chat durant le boss Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Texte de la Couleur Livid",
"text.autoconfig.skyblocker.option.general.bars.barpositions.LAYER1": "Couche 1",
"text.autoconfig.skyblocker.option.general.bars.barpositions.NONE": "Désactivé",
diff --git a/src/main/resources/assets/skyblocker/lang/pt_br.json b/src/main/resources/assets/skyblocker/lang/pt_br.json
index d0371642..f6362986 100644
--- a/src/main/resources/assets/skyblocker/lang/pt_br.json
+++ b/src/main/resources/assets/skyblocker/lang/pt_br.json
@@ -184,7 +184,7 @@
"text.autoconfig.skyblocker.option.locations.dungeons.enableMap": "Ativar mapa",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Tamanho do mapa",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Cor do Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Ativar cor para Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Ativar cor para Livid",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals": "Guia dos terminais",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveColor": "Guia de seleção colorido",
"text.autoconfig.skyblocker.option.locations.dungeons.terminals.solveOrder": "Guia de clique em ordem",
@@ -238,5 +238,5 @@
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow": "Brilho em Mobs com estrela",
"text.autoconfig.skyblocker.option.locations.dungeons.starredMobGlow.@Tooltip": "Aplicar o efeito de brilho para Mobs estrelados que estão visíveis.",
"text.autoconfig.skyblocker.option.locations.dungeons.solveTicTacToe": "Guia para o Puzzle do jogo da velha",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Mandar a cor do Livid no chat durante a luta contra Livid."
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Mandar a cor do Livid no chat durante a luta contra Livid."
}
diff --git a/src/main/resources/assets/skyblocker/lang/ru_ru.json b/src/main/resources/assets/skyblocker/lang/ru_ru.json
index 980c130a..d22f6274 100644
--- a/src/main/resources/assets/skyblocker/lang/ru_ru.json
+++ b/src/main/resources/assets/skyblocker/lang/ru_ru.json
@@ -82,9 +82,9 @@
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Текст, который будет отправлен в чат во время боя с Livid. Вместо \"[color]\" отправится цвет босса.",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[1]": "\nКрасивый: Показывает название, процент и шкалу выполнения, а также иконку.",
"text.autoconfig.skyblocker.option.locations.dungeons.mapScaling": "Размер Карты",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "Включить Цвет Босса Livid",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "Включить Цвет Босса Livid",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "Цвет Босса Livid",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "Отправляет в чат информацию о том, какого цвета босс Livid.",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "Отправляет в чат информацию о том, какого цвета босс Livid.",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "Текст О Цвете Livid",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style": "Стиль HUD",
"text.autoconfig.skyblocker.option.locations.dwarvenMines.dwarvenHud.style.@Tooltip[0]": "Упрощенный: Показывает название и процент выполнения.",
diff --git a/src/main/resources/assets/skyblocker/lang/zh_cn.json b/src/main/resources/assets/skyblocker/lang/zh_cn.json
index 4a3abde3..9f8bb08c 100644
--- a/src/main/resources/assets/skyblocker/lang/zh_cn.json
+++ b/src/main/resources/assets/skyblocker/lang/zh_cn.json
@@ -88,9 +88,9 @@
"text.autoconfig.skyblocker.option.general.fishing": "钓鱼助手",
"text.autoconfig.skyblocker.option.general.fishing.enableFishingHelper": "启用钓鱼助手",
"skyblocker.fishing.reelNow": "收竿!",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor": "启用真 Livid 的颜色提示",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText": "启用真 Livid 的颜色提示",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor": "提示真 Livid 的颜色",
- "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColor.@Tooltip": "将真 Livid 的颜色发送到聊天栏。",
+ "text.autoconfig.skyblocker.option.locations.dungeons.lividColor.enableLividColorText.@Tooltip": "将真 Livid 的颜色发送到聊天栏。",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText": "真 Livid 颜色提示信息",
"text.autoconfig.skyblocker.option.locations.dungeons.lividColor.lividColorText.@Tooltip": "Livid Boss战时发送到聊天栏的信息, 字段 “[color]” 将被替换为真 Livid 的颜色",
"key.skyblocker.defaultTgl": "将tab键所显示的列表改为默认空岛生存列表",
diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png
index fd8e8604..fd8e8604 100644
--- a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background.png
+++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_circular.png
Binary files differ
diff --git a/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png
new file mode 100644
index 00000000..0392b56c
--- /dev/null
+++ b/src/main/resources/assets/skyblocker/textures/gui/sprites/item_rarity_background_square.png
Binary files differ
diff --git a/src/main/resources/skyblocker.mixins.json b/src/main/resources/skyblocker.mixins.json
index 5bafb324..4e7bfe16 100644
--- a/src/main/resources/skyblocker.mixins.json
+++ b/src/main/resources/skyblocker.mixins.json
@@ -36,12 +36,7 @@
"accessor.PlayerListHudAccessor",
"accessor.RecipeBookWidgetAccessor",
"accessor.ScreenAccessor",
- "accessor.WorldRendererAccessor",
- "yacl.DoubleFieldControllerMixin",
- "yacl.FloatFieldControllerMixin",
- "yacl.IntegerFieldControllerMixin",
- "yacl.LongFieldControllerMixin",
- "yacl.NumberFieldControllerMixin"
+ "accessor.WorldRendererAccessor"
],
"injectors": {
"defaultRequire": 1
diff --git a/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java
new file mode 100644
index 00000000..0870e744
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/skyblock/dungeon/secrets/SecretWaypointTest.java
@@ -0,0 +1,79 @@
+package de.hysky.skyblocker.skyblock.dungeon.secrets;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.mojang.serialization.JsonOps;
+import net.minecraft.util.math.BlockPos;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.List;
+
+public class SecretWaypointTest {
+ private final Gson gson = new Gson();
+
+ @Test
+ void testCodecSerialize() {
+ SecretWaypoint waypoint = new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN);
+ JsonElement json = SecretWaypoint.CODEC.encodeStart(JsonOps.INSTANCE, waypoint).result().orElseThrow();
+ String expectedJson = "{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]}";
+
+ Assertions.assertEquals(expectedJson, json.toString());
+ }
+
+ @Test
+ void testCodecDeserialize() {
+ String json = "{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]}";
+ SecretWaypoint waypoint = SecretWaypoint.CODEC.parse(JsonOps.INSTANCE, gson.fromJson(json, JsonElement.class)).result().orElseThrow();
+ SecretWaypoint expectedWaypoint = new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN);
+
+ equal(expectedWaypoint, waypoint);
+ }
+
+ @Test
+ void testListCodecSerialize() {
+ List<SecretWaypoint> waypoints = List.of(new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN), new SecretWaypoint(1, SecretWaypoint.Category.CHEST, "name", new BlockPos(-1, 0, 1)));
+ JsonElement json = SecretWaypoint.LIST_CODEC.encodeStart(JsonOps.INSTANCE, waypoints).result().orElseThrow();
+ String expectedJson = "[{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]},{\"secretIndex\":1,\"category\":\"chest\",\"name\":{\"text\":\"name\"},\"pos\":[-1,0,1]}]";
+
+ Assertions.assertEquals(expectedJson, json.toString());
+ }
+
+ @Test
+ void testListCodecDeserialize() {
+ String json = "[{\"secretIndex\":0,\"category\":\"default\",\"name\":{\"text\":\"name\"},\"pos\":[0,0,0]},{\"secretIndex\":1,\"category\":\"chest\",\"name\":{\"text\":\"name\"},\"pos\":[-1,0,1]}]";
+ List<SecretWaypoint> waypoints = SecretWaypoint.LIST_CODEC.parse(JsonOps.INSTANCE, gson.fromJson(json, JsonElement.class)).result().orElseThrow();
+ List<SecretWaypoint> expectedWaypoints = List.of(new SecretWaypoint(0, SecretWaypoint.Category.DEFAULT, "name", BlockPos.ORIGIN), new SecretWaypoint(1, SecretWaypoint.Category.CHEST, "name", new BlockPos(-1, 0, 1)));
+
+ Assertions.assertEquals(expectedWaypoints.size(), waypoints.size());
+ for (int i = 0; i < expectedWaypoints.size(); i++) {
+ SecretWaypoint expectedWaypoint = expectedWaypoints.get(i);
+ SecretWaypoint waypoint = waypoints.get(i);
+ equal(expectedWaypoint, waypoint);
+ }
+ }
+
+ @Test
+ void testGetCategory() {
+ JsonObject waypointJson = new JsonObject();
+ waypointJson.addProperty("category", "chest");
+ SecretWaypoint.Category category = SecretWaypoint.Category.get(waypointJson);
+ Assertions.assertEquals(SecretWaypoint.Category.CHEST, category);
+ }
+
+ @Test
+ void testGetCategoryDefault() {
+ JsonObject waypointJson = new JsonObject();
+ waypointJson.addProperty("category", "");
+ SecretWaypoint.Category category = SecretWaypoint.Category.get(waypointJson);
+ Assertions.assertEquals(SecretWaypoint.Category.DEFAULT, category);
+ }
+
+ private static void equal(SecretWaypoint expectedWaypoint, SecretWaypoint waypoint) {
+ Assertions.assertEquals(expectedWaypoint.secretIndex, waypoint.secretIndex);
+ Assertions.assertEquals(expectedWaypoint.category, waypoint.category);
+ Assertions.assertEquals(expectedWaypoint.name, waypoint.name);
+ Assertions.assertEquals(expectedWaypoint.pos, waypoint.pos);
+ }
+}
diff --git a/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
index 85b01b4b..93d33070 100644
--- a/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
+++ b/src/test/java/de/hysky/skyblocker/skyblock/filters/ComboFilterTest.java
@@ -9,7 +9,7 @@ public class ComboFilterTest extends ChatFilterTest<ComboFilter> {
@Test
void testComboMF() {
- assertMatches("+5 Kill Combo +3% ✯ Magic Find");
+ assertMatches("+5 Kill Combo +3✯ Magic Find");
}
@Test
@@ -18,8 +18,13 @@ public class ComboFilterTest extends ChatFilterTest<ComboFilter> {
}
@Test
- void testComboEXP() {
- assertMatches("+20 Kill Combo +15% Combat Exp");
+ void testComboWisdom() {
+ assertMatches("+20 Kill Combo +15☯ Combat Wisdom");
+ }
+
+ @Test
+ void testComboNoBonus() {
+ assertMatches("+50 Kill Combo");
}
@Test
diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java
new file mode 100644
index 00000000..9dc5b2b9
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/ProfileAwareWaypointTest.java
@@ -0,0 +1,38 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import net.minecraft.util.math.BlockPos;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class ProfileAwareWaypointTest {
+ @Test
+ void testShouldRender() {
+ ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, null, null);
+ waypoint.setFound("profile");
+ Assertions.assertTrue(waypoint.shouldRender());
+ waypoint.setFound("");
+ Assertions.assertFalse(waypoint.shouldRender());
+ waypoint.setMissing();
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testGetColorComponents() {
+ ProfileAwareWaypoint waypoint = new ProfileAwareWaypoint(BlockPos.ORIGIN, null, new float[]{0f, 0.5f, 1f}, new float[]{1f, 0.5f, 0f});
+ waypoint.setFound("profile");
+ float[] colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(0f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(1f, colorComponents[2]);
+ waypoint.setFound("");
+ colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(1f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(0f, colorComponents[2]);
+ waypoint.setMissing();
+ colorComponents = waypoint.getColorComponents();
+ Assertions.assertEquals(0f, colorComponents[0]);
+ Assertions.assertEquals(0.5f, colorComponents[1]);
+ Assertions.assertEquals(1f, colorComponents[2]);
+ }
+}
diff --git a/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java
new file mode 100644
index 00000000..d8839951
--- /dev/null
+++ b/src/test/java/de/hysky/skyblocker/utils/waypoint/WaypointTest.java
@@ -0,0 +1,70 @@
+package de.hysky.skyblocker.utils.waypoint;
+
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.Box;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+public class WaypointTest {
+ private Waypoint.Type type;
+ private final float[] colorComponents = new float[]{0f, 0.5f, 1f};
+
+ @Test
+ void testDefaultConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertEquals(BlockPos.ORIGIN, waypoint.pos);
+ Assertions.assertEquals(new Box(BlockPos.ORIGIN), waypoint.box);
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ Assertions.assertEquals(0f, waypoint.colorComponents[0]);
+ Assertions.assertEquals(0.5f, waypoint.colorComponents[1]);
+ Assertions.assertEquals(1f, waypoint.colorComponents[2]);
+ Assertions.assertEquals(Waypoint.DEFAULT_HIGHLIGHT_ALPHA, waypoint.alpha);
+ Assertions.assertEquals(Waypoint.DEFAULT_LINE_WIDTH, waypoint.lineWidth);
+ Assertions.assertTrue(waypoint.throughWalls);
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testTypeConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, Waypoint.Type.WAYPOINT, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA);
+ Assertions.assertEquals(Waypoint.Type.WAYPOINT, waypoint.typeSupplier.get());
+ }
+
+ @Test
+ void testLineWidthConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, 10f);
+ Assertions.assertEquals(10f, waypoint.lineWidth);
+ }
+
+ @Test
+ void testThroughWallsConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, false);
+ Assertions.assertFalse(waypoint.throughWalls);
+ }
+
+ @Test
+ void testShouldRenderConstructor() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents, Waypoint.DEFAULT_HIGHLIGHT_ALPHA, Waypoint.DEFAULT_LINE_WIDTH, true, false);
+ Assertions.assertFalse(waypoint.shouldRender());
+ }
+
+ @Test
+ void testFound() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertTrue(waypoint.shouldRender());
+ waypoint.setFound();
+ Assertions.assertFalse(waypoint.shouldRender());
+ waypoint.setMissing();
+ Assertions.assertTrue(waypoint.shouldRender());
+ }
+
+ @Test
+ void testType() {
+ Waypoint waypoint = new Waypoint(BlockPos.ORIGIN, () -> type, colorComponents);
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ type = Waypoint.Type.WAYPOINT;
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ type = Waypoint.Type.OUTLINED_HIGHLIGHT;
+ Assertions.assertEquals(type, waypoint.typeSupplier.get());
+ }
+}