aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/me/xmrvizzy/skyblocker
diff options
context:
space:
mode:
authormsg-programs <msgdoesstuff@gmail.com>2023-08-06 15:46:54 +0200
committermsg-programs <msgdoesstuff@gmail.com>2023-08-06 15:46:54 +0200
commit11c921b7fa882d26a1ac8640fae121f43727984a (patch)
treefd46208bea4b3c784e885777492b53c05c7a1f23 /src/main/java/me/xmrvizzy/skyblocker
parentf8c6e9454cc1354714bf46f7763ff7faf7669ddf (diff)
parent8353ab29d85a5827fda151ab2b042419f6420bcb (diff)
downloadSkyblocker-11c921b7fa882d26a1ac8640fae121f43727984a.tar.gz
Skyblocker-11c921b7fa882d26a1ac8640fae121f43727984a.tar.bz2
Skyblocker-11c921b7fa882d26a1ac8640fae121f43727984a.zip
Merge branch 'master' of https://github.com/SkyblockerMod/Skyblocker into json-tabhud
# Conflicts: # src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java # src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java # src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/screens/main/GardenScreen.java # src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java Pull upstream changes
Diffstat (limited to 'src/main/java/me/xmrvizzy/skyblocker')
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java1
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/chat/filters/ShowOffFilter.java18
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java39
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java33
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java13
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java44
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/FarmlandBlockMixin.java20
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java12
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java40
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/InventoryScreenMixin.java17
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/LeverBlockMixin.java12
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java30
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerSkinProviderMixin.java20
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/ScoreboardMixin.java16
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/FrustumInvoker.java7
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/HandledScreenAccessor.java (renamed from src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenAccessor.java)2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/PlayerListHudAccessor.java (renamed from src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudAccessor.java)11
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/RecipeBookWidgetAccessor.java (renamed from src/main/java/me/xmrvizzy/skyblocker/mixin/RecipeBookWidgetAccessor.java)2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/WorldRendererAccessor.java (renamed from src/main/java/me/xmrvizzy/skyblocker/mixin/AccessorWorldRenderer.java)4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/TeleportOverlay.java112
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java40
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java28
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/OldLever.java18
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java68
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java6
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemFixerUpper.java418
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java32
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java6
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/rift/HealingMelonIndicator.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java206
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigListWidget.java232
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java107
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java5
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/CameraPositionWidget.java37
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java30
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/FrustumUtils.java6
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java45
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java2
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java15
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java37
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java48
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java29
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java4
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java7
-rw-r--r--src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainerConfigScreen.java4
52 files changed, 1441 insertions, 471 deletions
diff --git a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
index 91ae3740..6014ed51 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/SkyblockerMod.java
@@ -16,10 +16,12 @@ import me.xmrvizzy.skyblocker.skyblock.item.WikiLookup;
import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemRegistry;
import me.xmrvizzy.skyblocker.skyblock.quicknav.QuickNav;
import me.xmrvizzy.skyblocker.skyblock.rift.TheRift;
+import me.xmrvizzy.skyblocker.skyblock.shortcut.Shortcuts;
import me.xmrvizzy.skyblocker.skyblock.tabhud.TabHud;
import me.xmrvizzy.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster;
import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr;
import me.xmrvizzy.skyblocker.utils.*;
+import me.xmrvizzy.skyblocker.utils.culling.OcclusionCulling;
import me.xmrvizzy.skyblocker.utils.title.TitleContainer;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
@@ -76,6 +78,7 @@ public class SkyblockerMod implements ClientModInitializer {
QuickNav.init();
DwarvenHud.init();
ChatMessageListener.init();
+ Shortcuts.init();
DiscordRPCManager.init();
LividColor.init();
FishingHelper.init();
@@ -85,6 +88,8 @@ public class SkyblockerMod implements ClientModInitializer {
TheRift.init();
TitleContainer.init();
ScreenMaster.init();
+ OcclusionCulling.init();
+ TeleportOverlay.init();
containerSolverManager.init();
scheduler.scheduleCyclic(Utils::update, 20);
scheduler.scheduleCyclic(DiscordRPCManager::updateDataAndPresence, 100);
diff --git a/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java b/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java
index d58d03aa..5ea3e2a9 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/chat/ChatMessageListener.java
@@ -53,6 +53,7 @@ public interface ChatMessageListener {
new MoltenWaveFilter(),
new TeleportPadFilter(),
new AutopetFilter(),
+ new ShowOffFilter()
};
// Register all listeners to EVENT
for (ChatMessageListener listener : listeners) {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java
index 6b681d4c..a813346b 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/AdFilter.java
@@ -13,13 +13,14 @@ public class AdFilter extends ChatPatternListener {
Pattern.compile("^(?:i(?:m|'m| am)? |(?:is )?any(?: ?one|1) )?(?:buy|sell|lowball|trade?)(?:ing)?(?:\\W|$)", Pattern.CASE_INSENSITIVE),
Pattern.compile("(.)\\1{7,}"),
Pattern.compile("\\W(?:on|in|check|at) my (?:ah|bin)(?:\\W|$)", Pattern.CASE_INSENSITIVE), };
+ private static final String 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\u12DE";
public AdFilter() {
// Groups:
// 1. Player name
// 2. Message
- // (?:§8\[[§feadbc0-9]+§8\] )?(?:.+ )?§[67abc](?:\[[§A-Za-z0-9+]+\] )?([A-Za-z0-9_]+)§[f7]: (.+)
- super("(?:§8\\[[§feadbc0-9]+§8\\] )?(?:.+ )?§[67abc](?:\\[[§A-Za-z0-9+]+\\] )?([A-Za-z0-9_]+)§[f7]: (.+)");
+ // (?:§8\[[§feadbc0-9]+§8\] )?(?:[§76l]+[<INSERT EMBLEMS>] )?§[67abc](?:\[[§A-Za-z0-9+]+\] )?([A-Za-z0-9_]+)§[f7]: (.+)
+ super("(?:§8\\[[§feadbc0-9]+§8\\] )?(?:[§76l]+[" + EMBLEMS + "] )?§[67abc](?:\\[[§A-Za-z0-9+]+\\] )?([A-Za-z0-9_]+)§[f7]: (.+)");
}
@Override
diff --git a/src/main/java/me/xmrvizzy/skyblocker/chat/filters/ShowOffFilter.java b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/ShowOffFilter.java
new file mode 100644
index 00000000..3b5ea41a
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/chat/filters/ShowOffFilter.java
@@ -0,0 +1,18 @@
+package me.xmrvizzy.skyblocker.chat.filters;
+
+import me.xmrvizzy.skyblocker.chat.ChatFilterResult;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+
+public class ShowOffFilter extends SimpleChatFilter {
+ private static final String 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\u12DE";
+ private static final String[] SHOW_TYPES = { "is holding", "is wearing", "is friends with a", "has" };
+
+ public ShowOffFilter() {
+ super("(?:§8\\[[§feadbc0-9]+§8\\] )?(?:[§76l]+[" + EMBLEMS + "] )?§[67abc](?:\\[[§A-Za-z0-9+]+\\] )?([A-Za-z0-9_]+)[§f7]+ (?:" + String.join("|", SHOW_TYPES) + ") §8\\[(.+)§8\\]");
+ }
+
+ @Override
+ protected ChatFilterResult state() {
+ return SkyblockerConfig.get().messages.hideShowOff;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
index 36ac4472..ec4bc3ce 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/config/SkyblockerConfig.java
@@ -1,6 +1,5 @@
package me.xmrvizzy.skyblocker.config;
-import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import me.shedaniel.autoconfig.AutoConfig;
import me.shedaniel.autoconfig.ConfigData;
@@ -161,6 +160,10 @@ public class SkyblockerConfig implements ConfigData {
@ConfigEntry.Gui.CollapsibleObject()
public FairySouls fairySouls = new FairySouls();
+ @ConfigEntry.Category("shortcuts")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public Shortcuts shortcuts = new Shortcuts();
+
@ConfigEntry.Category("itemList")
@ConfigEntry.Gui.CollapsibleObject()
public ItemList itemList = new ItemList();
@@ -178,6 +181,10 @@ public class SkyblockerConfig implements ConfigData {
@ConfigEntry.Gui.CollapsibleObject()
public TitleContainer titleContainer = new TitleContainer();
+ @ConfigEntry.Category("Teleport Overlay")
+ @ConfigEntry.Gui.CollapsibleObject()
+ public TeleportOverlay teleportOverlay = new TeleportOverlay();
+
@ConfigEntry.Gui.Excluded
public List<Integer> lockedSlots = new ArrayList<>();
}
@@ -263,6 +270,15 @@ public class SkyblockerConfig implements ConfigData {
public boolean enableFairySoulsHelper = false;
}
+ public static class Shortcuts {
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableShortcuts = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableCommandShortcuts = true;
+ @ConfigEntry.Gui.Tooltip()
+ public boolean enableCommandArgShortcuts = true;
+ }
+
public static class Hitbox {
public boolean oldFarmlandHitbox = true;
public boolean oldLeverHitbox = false;
@@ -279,6 +295,15 @@ public class SkyblockerConfig implements ConfigData {
public Alignment alignment = Alignment.MIDDLE;
}
+ public static class TeleportOverlay {
+ public boolean enableTeleportOverlays = true;
+ public boolean enableWeirdTransmission = true;
+ public boolean enableInstantTransmission = true;
+ public boolean enableEtherTransmission = true;
+ public boolean enableSinrecallTransmission = true;
+ public boolean enableWitherImpact = true;
+ }
+
public enum Direction {
HORIZONTAL,
VERTICAL;
@@ -484,6 +509,9 @@ public class SkyblockerConfig implements ConfigData {
public ChatFilterResult hideCombo = ChatFilterResult.PASS;
@ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
public ChatFilterResult hideAutopet = ChatFilterResult.PASS;
+ @ConfigEntry.Gui.EnumHandler(option = ConfigEntry.Gui.EnumHandler.EnumDisplayOption.BUTTON)
+ @ConfigEntry.Gui.Tooltip
+ public ChatFilterResult hideShowOff = ChatFilterResult.PASS;
@ConfigEntry.Gui.Tooltip()
public boolean hideMana = false;
}
@@ -504,7 +532,7 @@ public class SkyblockerConfig implements ConfigData {
*/
public static void init() {
AutoConfig.register(SkyblockerConfig.class, GsonConfigSerializer::new);
- ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(literal("skyblocker").then(optionsLiteral("config")).then(optionsLiteral("options")))));
+ ClientCommandRegistrationCallback.EVENT.register(((dispatcher, registryAccess) -> dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(optionsLiteral("config")).then(optionsLiteral("options")))));
}
/**
@@ -514,11 +542,8 @@ public class SkyblockerConfig implements ConfigData {
* @return the command builder
*/
private static LiteralArgumentBuilder<FabricClientCommandSource> optionsLiteral(String name) {
- return literal(name).executes(context -> {
- // Don't immediately open the next screen as it will be closed by ChatScreen right after this command is executed
- SkyblockerMod.getInstance().scheduler.queueOpenScreen(AutoConfig.getConfigScreen(SkyblockerConfig.class, null));
- return Command.SINGLE_SUCCESS;
- });
+ // Don't immediately open the next screen as it will be closed by ChatScreen right after this command is executed
+ return literal(name).executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(AutoConfig.getConfigScreen(SkyblockerConfig.class, null)));
}
public static SkyblockerConfig get() {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java
index 0c27704d..7d187caa 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/gui/ContainerSolverManager.java
@@ -1,7 +1,7 @@
package me.xmrvizzy.skyblocker.gui;
import com.mojang.blaze3d.systems.RenderSystem;
-import me.xmrvizzy.skyblocker.mixin.HandledScreenAccessor;
+import me.xmrvizzy.skyblocker.mixin.accessor.HandledScreenAccessor;
import me.xmrvizzy.skyblocker.skyblock.dungeon.CroesusHelper;
import me.xmrvizzy.skyblocker.skyblock.dungeon.terminal.ColorTerminal;
import me.xmrvizzy.skyblocker.skyblock.dungeon.terminal.OrderTerminal;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
index 80c98473..2d109524 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayNetworkHandlerMixin.java
@@ -1,24 +1,35 @@
package me.xmrvizzy.skyblocker.mixin;
+import com.llamalad7.mixinextras.injector.WrapWithCondition;
+
+import dev.cbyrne.betterinject.annotations.Inject;
import me.xmrvizzy.skyblocker.skyblock.FishingHelper;
-import net.minecraft.client.MinecraftClient;
+import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.network.packet.s2c.play.PlaySoundS2CPacket;
-import org.spongepowered.asm.mixin.Final;
+import org.slf4j.Logger;
import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(ClientPlayNetworkHandler.class)
public abstract class ClientPlayNetworkHandlerMixin {
- @Shadow
- @Final
- private MinecraftClient client;
-
@Inject(method = "onPlaySound", at = @At("RETURN"))
- private void skyblockmod_onPlaySound(PlaySoundS2CPacket packet, CallbackInfo ci) {
- FishingHelper.onSound(client, packet);
+ private void skyblocker$onPlaySound(PlaySoundS2CPacket packet) {
+ FishingHelper.onSound(packet);
+ }
+
+ @WrapWithCondition(method = "onEntityPassengersSet", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;)V", remap = false))
+ private boolean skyblocker$cancelEntityPassengersWarning(Logger instance, String msg) {
+ return !Utils.isOnHypixel();
+ }
+
+ @WrapWithCondition(method = "onPlayerList", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false))
+ private boolean skyblocker$cancelPlayerListWarning(Logger instance, String format, Object arg) {
+ return !Utils.isOnHypixel();
+ }
+
+ @WrapWithCondition(method = "onTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;[Ljava/lang/Object;)V", remap = false))
+ private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object... arg) {
+ return !Utils.isOnHypixel();
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java
index e48e725e..ee1fc5b8 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ClientPlayerEntityMixin.java
@@ -1,17 +1,16 @@
package me.xmrvizzy.skyblocker.mixin;
import com.mojang.authlib.GameProfile;
+
+import dev.cbyrne.betterinject.annotations.Inject;
import me.xmrvizzy.skyblocker.skyblock.HotbarSlotLock;
import me.xmrvizzy.skyblocker.skyblock.rift.HealingMelonIndicator;
import me.xmrvizzy.skyblocker.utils.Utils;
-import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.network.ClientPlayerEntity;
import net.minecraft.client.world.ClientWorld;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(ClientPlayerEntity.class)
@@ -21,12 +20,12 @@ public abstract class ClientPlayerEntityMixin extends AbstractClientPlayerEntity
}
@Inject(method = "dropSelectedItem", at = @At("HEAD"), cancellable = true)
- public void skyblocker$dropSelectedItem(boolean dropEntireStack, CallbackInfoReturnable<Boolean> cir) {
+ public void skyblocker$dropSelectedItem(CallbackInfoReturnable<Boolean> cir) {
if (Utils.isOnSkyblock()) HotbarSlotLock.handleDropSelectedItem(this.getInventory().selectedSlot, cir);
}
- @Inject(method = "updateHealth", at = @At("HEAD"))
- public void skyblocker$updateHealth(float health, CallbackInfo info) {
- HealingMelonIndicator.updateHealth(MinecraftClient.getInstance());
+ @Inject(method = "updateHealth", at = @At("RETURN"))
+ public void skyblocker$updateHealth() {
+ HealingMelonIndicator.updateHealth();
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java
index a8a490b8..cd0ccefd 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/DrawContextMixin.java
@@ -1,40 +1,36 @@
package me.xmrvizzy.skyblocker.mixin;
-import java.awt.Color;
-import java.util.regex.Pattern;
-
-import org.jetbrains.annotations.Nullable;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
import com.mojang.blaze3d.systems.RenderSystem;
+import dev.cbyrne.betterinject.annotations.Arg;
+import dev.cbyrne.betterinject.annotations.Inject;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.utils.ItemUtils;
import me.xmrvizzy.skyblocker.utils.Utils;
-import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.ColorHelper;
+import org.spongepowered.asm.mixin.Final;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import java.awt.*;
+import java.util.regex.Pattern;
@Mixin(DrawContext.class)
public abstract class DrawContextMixin {
- @Shadow @Final private MatrixStack matrices;
-
- @Shadow
- public void fill(RenderLayer layer, int x1, int x2, int y1, int y2, int color) {
- }
-
- @Inject(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At("HEAD"))
- public void skyblocker$renderItemBar(TextRenderer textRenderer, ItemStack stack, int x, int y, @Nullable String countOverride, CallbackInfo ci) {
+ @Shadow
+ @Final
+ private MatrixStack matrices;
+
+ @Shadow
+ public abstract void fill(RenderLayer layer, int x1, int x2, int y1, int y2, int color);
+ @Inject(method = "drawItemInSlot(Lnet/minecraft/client/font/TextRenderer;Lnet/minecraft/item/ItemStack;IILjava/lang/String;)V", at = @At("HEAD"))
+ public void skyblocker$renderItemBar(@Arg ItemStack stack, @Arg(ordinal = 0) int x, @Arg(ordinal = 1) int y) {
if (Utils.isOnSkyblock() && SkyblockerConfig.get().locations.dwarvenMines.enableDrillFuel) {
if (!stack.isEmpty()) {
NbtCompound tag = stack.getNbt();
@@ -42,7 +38,7 @@ public abstract class DrawContextMixin {
if (tag.getCompound("ExtraAttributes").contains("drill_fuel")) {
float current = 3000.0F;
float max = 3000.0F;
-
+
for (String line : ItemUtils.getTooltipStrings(stack)) {
if (line.contains("Fuel: ")) {
String clear = Pattern.compile("[^0-9 /]").matcher(line).replaceAll("").trim();
@@ -52,17 +48,17 @@ public abstract class DrawContextMixin {
break;
}
}
-
+
matrices.push();
matrices.translate(0f, 0f, 200f);
RenderSystem.disableDepthTest();
-
+
float hue = Math.max(0.0F, 1.0F - (max - current) / max);
int width = Math.round(current / max * 13.0F);
Color color = Color.getHSBColor(hue / 3.0F, 1.0F, 1.0F);
this.fill(RenderLayer.getGuiOverlay(), x + 2, y + 13, x + 15, y + 15, 0xFF000000);
this.fill(RenderLayer.getGuiOverlay(), x + 2, y + 13, x + 2 + width, y + 14, ColorHelper.Argb.getArgb(color.getAlpha(), color.getRed(), color.getGreen(), color.getBlue()));
-
+
matrices.pop();
RenderSystem.enableDepthTest();
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/FarmlandBlockMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/FarmlandBlockMixin.java
index 761f8a68..b07390b7 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/FarmlandBlockMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/FarmlandBlockMixin.java
@@ -1,34 +1,38 @@
package me.xmrvizzy.skyblocker.mixin;
+import com.llamalad7.mixinextras.injector.ModifyReturnValue;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.FarmlandBlock;
-import net.minecraft.block.ShapeContext;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
+import net.minecraft.util.shape.VoxelShapes;
import net.minecraft.world.BlockView;
+import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
@Mixin(FarmlandBlock.class)
public abstract class FarmlandBlockMixin extends Block {
+ @Shadow
+ @Final
+ protected static VoxelShape SHAPE;
+
protected FarmlandBlockMixin(Settings settings) {
super(settings);
}
- @Inject(method = "getOutlineShape", at = @At("HEAD"), cancellable = true)
- public void skyblocker$onGetOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, CallbackInfoReturnable<VoxelShape> cir) {
- if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.hitbox.oldFarmlandHitbox)
- cir.setReturnValue(Block.createCuboidShape(0.0, 0.0, 0.0, 16.0, 16.0, 16.0));
+ @ModifyReturnValue(method = "getOutlineShape", at = @At("RETURN"))
+ private VoxelShape skyblocker$replaceOutlineShape(VoxelShape original) {
+ return Utils.isOnSkyblock() && SkyblockerConfig.get().general.hitbox.oldFarmlandHitbox ? VoxelShapes.fullCube() : original;
}
@SuppressWarnings("deprecation")
@Override
public VoxelShape getCullingShape(BlockState state, BlockView world, BlockPos pos) {
- return Block.createCuboidShape(0.0, 0.0, 0.0, 16.0, 15.0, 16.0);
+ return SHAPE;
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java
index 903d3992..8a57f752 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenMixin.java
@@ -30,16 +30,18 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+import java.util.Map;
+
@Mixin(HandledScreen.class)
public abstract class HandledScreenMixin extends Screen {
- protected HandledScreenMixin(Text title) {
- super(title);
- }
-
@Shadow
@Nullable
protected Slot focusedSlot;
+ protected HandledScreenMixin(Text title) {
+ super(title);
+ }
+
@Inject(at = @At("HEAD"), method = "keyPressed")
public void skyblocker$keyPressed(int keyCode, int scanCode, int modifiers, CallbackInfoReturnable<Boolean> cir) {
if (this.client != null && this.focusedSlot != null && keyCode != 256 && !this.client.options.inventoryKey.matchesKey(keyCode, scanCode) && WikiLookup.wikiLookup.matchesKey(keyCode, scanCode)) {
@@ -96,7 +98,7 @@ public abstract class HandledScreenMixin extends Screen {
superpairsSolver.setSuperpairsCurrentSlot(ItemStack.EMPTY);
} else if (experimentSolver instanceof UltrasequencerSolver ultrasequencerSolver && slot.getIndex() == ultrasequencerSolver.getUltrasequencerNextSlot()) {
int count = ultrasequencerSolver.getSlots().get(ultrasequencerSolver.getUltrasequencerNextSlot()).getCount() + 1;
- ultrasequencerSolver.getSlots().entrySet().stream().filter(entry -> entry.getValue().getCount() == count).findAny().ifPresentOrElse((entry) -> ultrasequencerSolver.setUltrasequencerNextSlot(entry.getKey()), () -> ultrasequencerSolver.setState(ExperimentSolver.State.END));
+ ultrasequencerSolver.getSlots().entrySet().stream().filter(entry -> entry.getValue().getCount() == count).findAny().map(Map.Entry::getKey).ifPresentOrElse(ultrasequencerSolver::setUltrasequencerNextSlot, () -> ultrasequencerSolver.setState(ExperimentSolver.State.END));
}
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java
index 7d9182b5..4cda73aa 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/InGameHudMixin.java
@@ -1,5 +1,6 @@
package me.xmrvizzy.skyblocker.mixin;
+import com.llamalad7.mixinextras.sugar.Local;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.skyblock.FancyStatusBars;
@@ -11,11 +12,8 @@ import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.InGameHud;
-import net.minecraft.entity.player.PlayerEntity;
-import net.minecraft.item.ItemStack;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
-
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
@@ -26,20 +24,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Environment(EnvType.CLIENT)
@Mixin(InGameHud.class)
public abstract class InGameHudMixin {
- //@Shadow
- //@Final
- //private static Identifier ICONS = new Identifier("textures/gui/icons.png");
@Unique
private static final Identifier SLOT_LOCK = new Identifier(SkyblockerMod.NAMESPACE, "textures/gui/slot_lock.png");
@Unique
-
private final StatusBarTracker statusBarTracker = SkyblockerMod.getInstance().statusBarTracker;
@Unique
private final FancyStatusBars statusBars = new FancyStatusBars();
- @Unique
- private DrawContext hotbarContext;
- @Unique
- private int hotbarSlotIndex;
@Shadow
private int scaledHeight;
@@ -47,8 +37,7 @@ public abstract class InGameHudMixin {
private int scaledWidth;
@Shadow
- public void setOverlayMessage(Text message, boolean tinted) {
- }
+ public abstract void setOverlayMessage(Text message, boolean tinted);
@Inject(method = "setOverlayMessage(Lnet/minecraft/text/Text;Z)V", at = @At("HEAD"), cancellable = true)
private void skyblocker$onSetOverlayMessage(Text message, boolean tinted, CallbackInfo ci) {
@@ -63,26 +52,15 @@ public abstract class InGameHudMixin {
}
}
- @Inject(method = "renderHotbar", at = @At("HEAD"))
- public void skyblocker$renderHotbar(float f, DrawContext context, CallbackInfo ci) {
- if (Utils.isOnSkyblock()) {
- hotbarContext = context;
- hotbarSlotIndex = 0;
- }
- }
-
- @Inject(method = "renderHotbarItem", at = @At("HEAD"))
- public void skyblocker$renderHotbarItem(DrawContext context, int i, int j, float f, PlayerEntity player, ItemStack stack, int seed, CallbackInfo ci) {
- if (Utils.isOnSkyblock()) {
- if (HotbarSlotLock.isLocked(hotbarSlotIndex)) {
- hotbarContext.drawTexture(SLOT_LOCK, i, j, 0, 0, 16, 16);
- }
- hotbarSlotIndex++;
+ @Inject(method = "renderHotbar", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/hud/InGameHud;renderHotbarItem(Lnet/minecraft/client/gui/DrawContext;IIFLnet/minecraft/entity/player/PlayerEntity;Lnet/minecraft/item/ItemStack;I)V", ordinal = 0))
+ public void skyblocker$renderHotbarItemLock(float tickDelta, DrawContext context, CallbackInfo ci, @Local(ordinal = 4, name = "m") int index, @Local(ordinal = 5, name = "n") int x, @Local(ordinal = 6, name = "o") int y) {
+ if (Utils.isOnSkyblock() && HotbarSlotLock.isLocked(index)) {
+ context.drawTexture(SLOT_LOCK, x, y, 0, 0, 16, 16);
}
}
@Inject(method = "renderExperienceBar", at = @At("HEAD"), cancellable = true)
- private void skyblocker$renderExperienceBar(DrawContext context, int x, CallbackInfo ci) {
+ private void skyblocker$renderExperienceBar(CallbackInfo ci) {
if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.bars.enableBars && !Utils.isInTheRift())
ci.cancel();
}
@@ -96,12 +74,10 @@ public abstract class InGameHudMixin {
if (Utils.isInDungeons() && SkyblockerConfig.get().locations.dungeons.enableMap)
DungeonMap.render(context.getMatrices());
-
- //RenderSystem.setShaderTexture(0, ICONS);
}
@Inject(method = "renderMountHealth", at = @At("HEAD"), cancellable = true)
- private void skyblocker$renderMountHealth(DrawContext context, CallbackInfo ci) {
+ private void skyblocker$renderMountHealth(CallbackInfo ci) {
if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.bars.enableBars && !Utils.isInTheRift())
ci.cancel();
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/InventoryScreenMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/InventoryScreenMixin.java
index 64a1a4fe..729124fd 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/InventoryScreenMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/InventoryScreenMixin.java
@@ -1,5 +1,6 @@
package me.xmrvizzy.skyblocker.mixin;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.skyblock.itemlist.ItemListWidget;
import me.xmrvizzy.skyblocker.utils.Utils;
@@ -7,21 +8,11 @@ import net.minecraft.client.gui.screen.ingame.InventoryScreen;
import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Redirect;
@Mixin(InventoryScreen.class)
public abstract class InventoryScreenMixin {
- @Redirect(
- method = "<init>",
- at = @At(
- value = "NEW",
- target = "net/minecraft/client/gui/screen/recipebook/RecipeBookWidget"
- )
- )
- RecipeBookWidget skyblocker$constructor() {
- if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.itemList.enableItemList)
- return new ItemListWidget();
- else
- return new RecipeBookWidget();
+ @ModifyExpressionValue(method = "<init>", at = @At(value = "NEW", target = "net/minecraft/client/gui/screen/recipebook/RecipeBookWidget"))
+ private RecipeBookWidget skyblocker$replaceRecipeBook(RecipeBookWidget original) {
+ return SkyblockerConfig.get().general.itemList.enableItemList && Utils.isOnSkyblock() ? new ItemListWidget() : original;
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/LeverBlockMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/LeverBlockMixin.java
index 505de202..d65b93a2 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/LeverBlockMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/LeverBlockMixin.java
@@ -4,16 +4,15 @@ import me.xmrvizzy.skyblocker.skyblock.dungeon.OldLever;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.block.BlockState;
import net.minecraft.block.LeverBlock;
-import net.minecraft.block.ShapeContext;
import net.minecraft.block.WallMountedBlock;
-import net.minecraft.util.math.BlockPos;
import net.minecraft.util.shape.VoxelShape;
-import net.minecraft.world.BlockView;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
+import dev.cbyrne.betterinject.annotations.Arg;
+import dev.cbyrne.betterinject.annotations.Inject;
+
@Mixin(LeverBlock.class)
public abstract class LeverBlockMixin extends WallMountedBlock {
protected LeverBlockMixin(Settings settings) {
@@ -21,11 +20,10 @@ public abstract class LeverBlockMixin extends WallMountedBlock {
}
@Inject(method = "getOutlineShape", at = @At("HEAD"), cancellable = true)
- public void skyblocker$onGetOutlineShape(BlockState state, BlockView world, BlockPos pos, ShapeContext context, CallbackInfoReturnable<VoxelShape> cir) {
+ public void skyblocker$onGetOutlineShape(@Arg BlockState state, CallbackInfoReturnable<VoxelShape> cir) {
if (Utils.isOnSkyblock()) {
VoxelShape shape = OldLever.getShape(state.get(FACE), state.get(FACING));
- if (shape != null)
- cir.setReturnValue(shape);
+ if (shape != null) cir.setReturnValue(shape);
}
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java
index 0c1977fe..85f179e4 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/MinecraftClientMixin.java
@@ -8,8 +8,7 @@ import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+import dev.cbyrne.betterinject.annotations.Inject;
@Mixin(MinecraftClient.class)
public abstract class MinecraftClientMixin {
@@ -18,7 +17,7 @@ public abstract class MinecraftClientMixin {
public ClientPlayerEntity player;
@Inject(method = "handleInputEvents", at = @At("HEAD"))
- public void skyblocker$handleInputEvents(CallbackInfo ci) {
+ public void skyblocker$handleInputEvents() {
if (Utils.isOnSkyblock()) {
HotbarSlotLock.handleInputEvents(player);
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java
index a4098ce5..ec7b6ddd 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudMixin.java
@@ -1,11 +1,5 @@
package me.xmrvizzy.skyblocker.mixin;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.skyblock.tabhud.TabHud;
import me.xmrvizzy.skyblocker.skyblock.tabhud.screenbuilder.ScreenMaster;
@@ -17,34 +11,32 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.hud.PlayerListHud;
import net.minecraft.client.network.ClientPlayNetworkHandler;
-import net.minecraft.scoreboard.Scoreboard;
-import net.minecraft.scoreboard.ScoreboardObjective;
import net.minecraft.text.Text;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import dev.cbyrne.betterinject.annotations.Arg;
+import dev.cbyrne.betterinject.annotations.Inject;
@Environment(EnvType.CLIENT)
@Mixin(PlayerListHud.class)
public class PlayerListHudMixin {
-
@Shadow
private Text footer;
@Inject(at = @At("HEAD"), method = "render(Lnet/minecraft/client/gui/DrawContext;ILnet/minecraft/scoreboard/Scoreboard;Lnet/minecraft/scoreboard/ScoreboardObjective;)V", cancellable = true)
- public void skyblocker$renderTabHud(DrawContext context, int scaledW, Scoreboard sb, ScoreboardObjective sbo,
- CallbackInfo info) {
-
- if (!Utils.isOnSkyblock()
- || !SkyblockerConfig.get().general.tabHud.tabHudEnabled
- || TabHud.defaultTgl.isPressed()) {
+ public void skyblocker$renderTabHud(@Arg DrawContext context, @Arg int w, CallbackInfo info) {
+ if (!Utils.isOnSkyblock() || !SkyblockerConfig.get().general.tabHud.tabHudEnabled || TabHud.defaultTgl.isPressed()) {
return;
}
- MinecraftClient client = MinecraftClient.getInstance();
- ClientPlayNetworkHandler nwH = client.getNetworkHandler();
+ ClientPlayNetworkHandler nwH = MinecraftClient.getInstance().getNetworkHandler();
if (nwH == null) {
return;
}
- int w = scaledW;
int h = MinecraftClient.getInstance().getWindow().getScaledHeight();
float scale = SkyblockerConfig.get().general.tabHud.tabHudScale / 100f;
w = (int) (w / scale);
@@ -58,7 +50,7 @@ public class PlayerListHudMixin {
// screen.render(context);
info.cancel();
} catch (Exception e) {
- TabHud.LOGGER.error("Drawing default hud. Reason: Screen exception {}", e);
+ TabHud.LOGGER.error("[Skyblocker] Encountered unknown exception while drawing default hud", e);
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerSkinProviderMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerSkinProviderMixin.java
new file mode 100644
index 00000000..a382a58e
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerSkinProviderMixin.java
@@ -0,0 +1,20 @@
+package me.xmrvizzy.skyblocker.mixin;
+
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.minecraft.client.texture.PlayerSkinProvider;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.ModifyVariable;
+
+@Mixin(PlayerSkinProvider.class)
+public class PlayerSkinProviderMixin {
+ @ModifyVariable(method = "loadSkin(Lcom/mojang/authlib/GameProfile;Lnet/minecraft/client/texture/PlayerSkinProvider$SkinTextureAvailableCallback;Z)V", at = @At("STORE"))
+ private Runnable skyblocker$removeInvalidBase64LogSpam(Runnable runnable) {
+ return Utils.isOnHypixel() ? () -> {
+ try {
+ runnable.run();
+ } catch (IllegalArgumentException ignored) {
+ }
+ } : runnable;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/ScoreboardMixin.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/ScoreboardMixin.java
new file mode 100644
index 00000000..90edde6f
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/ScoreboardMixin.java
@@ -0,0 +1,16 @@
+package me.xmrvizzy.skyblocker.mixin;
+
+import com.llamalad7.mixinextras.injector.WrapWithCondition;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.minecraft.scoreboard.Scoreboard;
+import org.slf4j.Logger;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+@Mixin(Scoreboard.class)
+public abstract class ScoreboardMixin {
+ @WrapWithCondition(method = "addTeam", at = @At(value = "INVOKE", target = "Lorg/slf4j/Logger;warn(Ljava/lang/String;Ljava/lang/Object;)V", remap = false))
+ private boolean skyblocker$cancelTeamWarning(Logger instance, String format, Object arg) {
+ return !Utils.isOnHypixel();
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/FrustumInvoker.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/FrustumInvoker.java
index 108a7344..3cde115e 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/FrustumInvoker.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/FrustumInvoker.java
@@ -1,15 +1,14 @@
package me.xmrvizzy.skyblocker.mixin.accessor;
-import me.xmrvizzy.skyblocker.utils.FrustumUtils;
import net.minecraft.client.render.Frustum;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Invoker;
/**
- * Use {@link FrustumUtils#isVisible(double, double, double, double, double, double) FrustumUtils#isVisible} which is shorter. For the purpose of avoiding object allocations!
+ * Use {@link me.xmrvizzy.skyblocker.utils.FrustumUtils#isVisible(double, double, double, double, double, double) FrustumUtils#isVisible} which is shorter. For the purpose of avoiding object allocations!
*/
@Mixin(Frustum.class)
public interface FrustumInvoker {
- @Invoker("isVisible")
- boolean isVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ);
+ @Invoker
+ boolean invokeIsVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ);
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenAccessor.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/HandledScreenAccessor.java
index ea497b75..ad35dae6 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/HandledScreenAccessor.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/HandledScreenAccessor.java
@@ -1,4 +1,4 @@
-package me.xmrvizzy.skyblocker.mixin;
+package me.xmrvizzy.skyblocker.mixin.accessor;
import net.minecraft.client.gui.screen.ingame.HandledScreen;
import org.spongepowered.asm.mixin.Mixin;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudAccessor.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/PlayerListHudAccessor.java
index db329775..7e335d73 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/PlayerListHudAccessor.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/PlayerListHudAccessor.java
@@ -1,18 +1,17 @@
-package me.xmrvizzy.skyblocker.mixin;
-
-import java.util.Comparator;
+package me.xmrvizzy.skyblocker.mixin.accessor;
+import net.minecraft.client.gui.hud.PlayerListHud;
+import net.minecraft.client.network.PlayerListEntry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
-import net.minecraft.client.gui.hud.PlayerListHud;
-import net.minecraft.client.network.PlayerListEntry;
+import java.util.Comparator;
@Mixin(PlayerListHud.class)
public interface PlayerListHudAccessor {
@Accessor("ENTRY_ORDERING")
- public static Comparator<PlayerListEntry> getOrdering() {
+ static Comparator<PlayerListEntry> getOrdering() {
throw new AssertionError();
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/RecipeBookWidgetAccessor.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/RecipeBookWidgetAccessor.java
index 808b2950..0f20d4e4 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/RecipeBookWidgetAccessor.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/RecipeBookWidgetAccessor.java
@@ -1,4 +1,4 @@
-package me.xmrvizzy.skyblocker.mixin;
+package me.xmrvizzy.skyblocker.mixin.accessor;
import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget;
import net.minecraft.client.gui.widget.TextFieldWidget;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/mixin/AccessorWorldRenderer.java b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/WorldRendererAccessor.java
index e9067851..831a3385 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/mixin/AccessorWorldRenderer.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/mixin/accessor/WorldRendererAccessor.java
@@ -1,4 +1,4 @@
-package me.xmrvizzy.skyblocker.mixin;
+package me.xmrvizzy.skyblocker.mixin.accessor;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@@ -7,7 +7,7 @@ import net.minecraft.client.render.Frustum;
import net.minecraft.client.render.WorldRenderer;
@Mixin(WorldRenderer.class)
-public interface AccessorWorldRenderer {
+public interface WorldRendererAccessor {
@Accessor
Frustum getFrustum();
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java
index 8dee3fcb..b53157c5 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/FishingHelper.java
@@ -44,10 +44,10 @@ public class FishingHelper {
startTime = 0;
}
- public static void onSound(MinecraftClient client, PlaySoundS2CPacket packet) {
+ public static void onSound(PlaySoundS2CPacket packet) {
String path = packet.getSound().value().getId().getPath();
if (SkyblockerConfig.get().general.fishing.enableFishingHelper && startTime != 0 && System.currentTimeMillis() >= startTime + 2000 && ("entity.generic.splash".equals(path) || "entity.player.splash".equals(path))) {
- ClientPlayerEntity player = client.player;
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (player != null && player.fishHook != null) {
Vec3d soundToFishHook = player.fishHook.getPos().subtract(packet.getX(), 0, packet.getZ());
if (Math.abs(normalYawVector.x * soundToFishHook.z - normalYawVector.z * soundToFishHook.x) < 0.2D && Math.abs(normalYawVector.dotProduct(soundToFishHook)) < 4D && player.getPos().squaredDistanceTo(packet.getX(), packet.getY(), packet.getZ()) > 1D) {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/TeleportOverlay.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/TeleportOverlay.java
new file mode 100644
index 00000000..e7c76160
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/TeleportOverlay.java
@@ -0,0 +1,112 @@
+package me.xmrvizzy.skyblocker.skyblock;
+
+import com.mojang.blaze3d.systems.RenderSystem;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+import me.xmrvizzy.skyblocker.skyblock.item.PriceInfoTooltip;
+import me.xmrvizzy.skyblocker.utils.RenderHelper;
+import me.xmrvizzy.skyblocker.utils.Utils;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
+import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.minecraft.block.BlockState;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NbtCompound;
+import net.minecraft.util.hit.BlockHitResult;
+import net.minecraft.util.hit.HitResult;
+import net.minecraft.util.math.BlockPos;
+
+public class TeleportOverlay {
+ private static final float[] COLOR_COMPONENTS = {118f / 255f, 21f / 255f, 148f / 255f};
+ private static final MinecraftClient client = MinecraftClient.getInstance();
+
+ public static void init() {
+ WorldRenderEvents.AFTER_TRANSLUCENT.register(TeleportOverlay::render);
+ }
+
+ private static void render(WorldRenderContext wrc) {
+ if (Utils.isOnSkyblock() && SkyblockerConfig.get().general.teleportOverlay.enableTeleportOverlays && client.player != null && client.world != null) {
+ ItemStack heldItem = client.player.getMainHandStack();
+ String itemId = PriceInfoTooltip.getInternalNameFromNBT(heldItem);
+ NbtCompound nbt = heldItem.getNbt();
+
+ if (itemId != null) {
+ switch (itemId) {
+ case "ASPECT_OF_THE_LEECH_1" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableWeirdTransmission) {
+ render(wrc, 3);
+ }
+ }
+ case "ASPECT_OF_THE_LEECH_2" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableWeirdTransmission) {
+ render(wrc, 4);
+ }
+ }
+ case "ASPECT_OF_THE_END", "ASPECT_OF_THE_VOID" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableEtherTransmission && client.options.sneakKey.isPressed() && nbt != null && nbt.getCompound("ExtraAttributes").getInt("ethermerge") == 1) {
+ render(wrc, nbt, 57);
+ } else if (SkyblockerConfig.get().general.teleportOverlay.enableInstantTransmission) {
+ render(wrc, nbt, 8);
+ }
+ }
+ case "ETHERWARP_CONDUIT" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableEtherTransmission) {
+ render(wrc, nbt, 57);
+ }
+ }
+ case "SINSEEKER_SCYTHE" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableSinrecallTransmission) {
+ render(wrc, nbt, 4);
+ }
+ }
+ case "NECRON_BLADE", "ASTRAEA", "HYPERION", "SCYLLA", "VALKYRIE" -> {
+ if (SkyblockerConfig.get().general.teleportOverlay.enableWitherImpact) {
+ render(wrc, 10);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Renders the teleport overlay with a given base range and the tuned transmission stat.
+ */
+ private static void render(WorldRenderContext wrc, NbtCompound nbt, int baseRange) {
+ render(wrc, nbt != null && nbt.getCompound("ExtraAttributes").contains("tuned_transmission") ? baseRange + nbt.getCompound("ExtraAttributes").getInt("tuned_transmission") : baseRange);
+ }
+
+ /**
+ * Renders the teleport overlay with a given range. Uses {@link MinecraftClient#crosshairTarget} if it is a block and within range. Otherwise, raycasts from the player with the given range.
+ * @implNote {@link MinecraftClient#player} and {@link MinecraftClient#world} must not be null when calling this method.
+ */
+ private static void render(WorldRenderContext wrc, int range) {
+ if (client.crosshairTarget != null && client.crosshairTarget.getType() == HitResult.Type.BLOCK && client.crosshairTarget instanceof BlockHitResult blockHitResult && client.crosshairTarget.squaredDistanceTo(client.player) < range * range) {
+ render(wrc, blockHitResult);
+ } else if (client.interactionManager != null && range > client.interactionManager.getReachDistance()) {
+ @SuppressWarnings("DataFlowIssue")
+ HitResult result = client.player.raycast(range, wrc.tickDelta(), false);
+ if (result.getType() == HitResult.Type.BLOCK && result instanceof BlockHitResult blockHitResult) {
+ render(wrc, blockHitResult);
+ }
+ }
+ }
+
+ /**
+ * Renders the teleport overlay at the given {@link BlockHitResult}.
+ * @implNote {@link MinecraftClient#world} must not be null when calling this method.
+ */
+ private static void render(WorldRenderContext wrc, BlockHitResult blockHitResult) {
+ BlockPos pos = blockHitResult.getBlockPos();
+ @SuppressWarnings("DataFlowIssue")
+ BlockState state = client.world.getBlockState(pos);
+ if (!state.isAir() && client.world.getBlockState(pos.up()).isAir() && client.world.getBlockState(pos.up(2)).isAir()) {
+ RenderSystem.polygonOffset(-1f, -10f);
+ RenderSystem.enablePolygonOffset();
+
+ RenderHelper.renderFilledIfVisible(wrc, pos, COLOR_COMPONENTS, 0.5f);
+
+ RenderSystem.polygonOffset(0f, 0f);
+ RenderSystem.disablePolygonOffset();
+ }
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java
index 2d868782..44c8803f 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/CroesusHelper.java
@@ -25,7 +25,7 @@ public class CroesusHelper extends ContainerSolver {
List<ColorHighlight> highlights = new ArrayList<>();
for (Map.Entry<Integer, ItemStack> entry : slots.entrySet()) {
ItemStack stack = entry.getValue();
- if (stack != null && stack.getNbt() != null && stack.getNbt().toString().contains("opened")) {
+ if (stack != null && stack.getNbt() != null && stack.getNbt().toString().contains("No more Chests to open!")) {
highlights.add(ColorHighlight.gray(entry.getKey()));
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java
index 2a97d0ee..29a6e687 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMap.java
@@ -1,9 +1,6 @@
package me.xmrvizzy.skyblocker.skyblock.dungeon;
-import org.apache.commons.lang3.StringUtils;
-
-import com.mojang.brigadier.Command;
-
+import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
@@ -16,11 +13,11 @@ import net.minecraft.item.FilledMapItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.map.MapState;
import net.minecraft.nbt.NbtCompound;
-import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
+import org.apache.commons.lang3.StringUtils;
public class DungeonMap {
- private static final Identifier MAP_BACKGROUND = new Identifier("textures/map/map_background.png");
+ private static final Identifier MAP_BACKGROUND = new Identifier("textures/map/map_background.png");
public static void render(MatrixStack matrices) {
MinecraftClient client = MinecraftClient.getInstance();
@@ -36,36 +33,29 @@ public class DungeonMap {
MapRenderer map = client.gameRenderer.getMapRenderer();
MapState state = FilledMapItem.getMapState(mapid, client.world);
float scaling = SkyblockerConfig.get().locations.dungeons.mapScaling;
- int x = SkyblockerConfig.get().locations.dungeons.mapX;
- int y = SkyblockerConfig.get().locations.dungeons.mapY;
+ int x = SkyblockerConfig.get().locations.dungeons.mapX;
+ int y = SkyblockerConfig.get().locations.dungeons.mapY;
if (state == null) return;
matrices.push();
matrices.translate(x, y, 0);
matrices.scale(scaling, scaling, 0f);
- map.draw( matrices, vertices, mapid, state, false, 15728880);
+ map.draw(matrices, vertices, mapid, state, false, 15728880);
vertices.draw();
matrices.pop();
}
}
-
+
public static void renderHUDMap(DrawContext context, int x, int y) {
- float scaling = SkyblockerConfig.get().locations.dungeons.mapScaling;
- int size = (int) (128 * scaling);
- context.drawTexture(MAP_BACKGROUND, x, y, 0, 0, size, size, size, size);
+ float scaling = SkyblockerConfig.get().locations.dungeons.mapScaling;
+ int size = (int) (128 * scaling);
+ context.drawTexture(MAP_BACKGROUND, x, y, 0, 0, size, size, size, size);
}
-
+
public static void init() {
- ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> {
- dispatcher.register(ClientCommandManager.literal("skyblocker")
- .then(ClientCommandManager.literal("hud")
- .then(ClientCommandManager.literal("dungeonmap")
- .executes(context -> {
- MinecraftClient client = context.getSource().getClient();
- client.send(() -> client.setScreen(new DungeonMapConfigScreen(Text.literal("Dungeon Map Config"))));
-
- return Command.SINGLE_SUCCESS;
- }))));
- });
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
+ .then(ClientCommandManager.literal("hud")
+ .then(ClientCommandManager.literal("dungeonmap")
+ .executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(DungeonMapConfigScreen::new))))));
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
index ffd7a8b6..ef782c3b 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/DungeonMapConfigScreen.java
@@ -10,43 +10,43 @@ import net.minecraft.client.gui.screen.Screen;
import net.minecraft.text.Text;
public class DungeonMapConfigScreen extends Screen {
-
+
private int hudX = SkyblockerConfig.get().locations.dungeons.mapX;
private int hudY = SkyblockerConfig.get().locations.dungeons.mapY;
-
- protected DungeonMapConfigScreen(Text title) {
- super(title);
+
+ protected DungeonMapConfigScreen() {
+ super(Text.literal("Dungeon Map Config"));
}
-
+
@Override
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
super.render(context, mouseX, mouseY, delta);
renderBackground(context);
DungeonMap.renderHUDMap(context, hudX, hudY);
- context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width / 2, height / 2, Color.GRAY.getRGB());
+ context.drawCenteredTextWithShadow(textRenderer, "Right Click To Reset Position", width >> 1, height >> 1, Color.GRAY.getRGB());
}
-
+
@Override
public boolean mouseDragged(double mouseX, double mouseY, int button, double deltaX, double deltaY) {
float scaling = SkyblockerConfig.get().locations.dungeons.mapScaling;
int size = (int) (128 * scaling);
- if(RenderUtils.pointExistsInArea((int) mouseX, (int) mouseY, hudX, hudY, hudX + size, hudY + size) && button == 0) {
- hudX = (int) Math.max(Math.min(mouseX - (size / 2), this.width - size), 0);
- hudY = (int) Math.max(Math.min(mouseY - (size / 2), this.height - size), 0);
+ if (RenderUtils.pointExistsInArea((int) mouseX, (int) mouseY, hudX, hudY, hudX + size, hudY + size) && button == 0) {
+ hudX = (int) Math.max(Math.min(mouseX - (size >> 1), this.width - size), 0);
+ hudY = (int) Math.max(Math.min(mouseY - (size >> 1), this.height - size), 0);
}
return super.mouseDragged(mouseX, mouseY, button, deltaX, deltaY);
}
-
+
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if(button == 1) {
+ if (button == 1) {
hudX = 2;
hudY = 2;
}
-
+
return super.mouseClicked(mouseX, mouseY, button);
}
-
+
@Override
public void close() {
SkyblockerConfig.get().locations.dungeons.mapX = hudX;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/OldLever.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/OldLever.java
index 37320c92..13789fe1 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/OldLever.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dungeon/OldLever.java
@@ -7,11 +7,11 @@ import net.minecraft.util.math.Direction;
import net.minecraft.util.shape.VoxelShape;
public class OldLever {
- protected static final VoxelShape FLOOR_SHAPE;
- protected static final VoxelShape NORTH_SHAPE;
- protected static final VoxelShape SOUTH_SHAPE;
- protected static final VoxelShape EAST_SHAPE;
- protected static final VoxelShape WEST_SHAPE;
+ protected static final VoxelShape FLOOR_SHAPE = Block.createCuboidShape(4.0D, 0.0D, 4.0D, 12.0D, 10.0D, 12.0D);
+ protected static final VoxelShape NORTH_SHAPE = Block.createCuboidShape(5.0D, 3.0D, 10.0D, 11.0D, 13.0D, 16.0D);
+ protected static final VoxelShape SOUTH_SHAPE = Block.createCuboidShape(5.0D, 3.0D, 0.0D, 11.0D, 13.0D, 6.0D);
+ protected static final VoxelShape EAST_SHAPE = Block.createCuboidShape(0.0D, 3.0D, 5.0D, 6.0D, 13.0D, 11.0D);
+ protected static final VoxelShape WEST_SHAPE = Block.createCuboidShape(10.0D, 3.0D, 5.0D, 16.0D, 13.0D, 11.0D);
public static VoxelShape getShape(WallMountLocation wallMountLocation, Direction direction) {
if (!SkyblockerConfig.get().general.hitbox.oldLeverHitbox)
@@ -37,12 +37,4 @@ public class OldLever {
}
return null;
}
-
- static {
- FLOOR_SHAPE = Block.createCuboidShape(4, 0, 4, 12, 10, 12);
- NORTH_SHAPE = Block.createCuboidShape(5.0D, 3.0D, 10.0D, 11.0D, 13.0D, 16.0D);
- SOUTH_SHAPE = Block.createCuboidShape(5.0D, 3.0D, 0.0D, 11.0D, 13.0D, 6.0D);
- WEST_SHAPE = Block.createCuboidShape(10.0D, 3.0D, 5.0D, 16.0D, 13.0D, 11.0D);
- EAST_SHAPE = Block.createCuboidShape(0.0D, 3.0D, 5.0D, 6.0D, 13.0D, 11.0D);
- }
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java
index 21a1b2d0..999a3163 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHud.java
@@ -1,12 +1,6 @@
package me.xmrvizzy.skyblocker.skyblock.dwarven;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
+import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.hud.HudCommsWidget;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
@@ -17,8 +11,14 @@ import net.minecraft.client.gui.DrawContext;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-public class DwarvenHud {
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+public class DwarvenHud {
public static final MinecraftClient client = MinecraftClient.getInstance();
public static List<Commission> commissionList = new ArrayList<>();
@@ -35,33 +35,32 @@ public class DwarvenHud {
"2x Mithril Powder Collector",
"(?:Ruby|Amber|Sapphire|Jade|Amethyst|Topaz) Gemstone Collector",
"(?:Amber|Sapphire|Jade|Amethyst|Topaz) Crystal Hunter",
- "Chest Looter"
- ).map(s -> Pattern.compile("^.*(" + s + "): (\\d+\\.?\\d*%|DONE)"))
+ "Chest Looter").map(s -> Pattern.compile("^.*(" + s + "): (\\d+\\.?\\d*%|DONE)"))
.collect(Collectors.toList());
public static void init() {
- ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
- .then(ClientCommandManager.literal("hud")
- .then(ClientCommandManager.literal("dwarven")
- .executes(context -> {
- client.send(() -> client.setScreen(new DwarvenHudConfigScreen(Text.of("Dwarven HUD Config"))));
- return 1;
- })))));
+ ClientCommandRegistrationCallback.EVENT.register((dispatcher,
+ registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
+ .then(ClientCommandManager.literal("hud")
+ .then(ClientCommandManager.literal("dwarven")
+ .executes(context -> SkyblockerMod.getInstance().scheduler
+ .queueOpenScreen(DwarvenHudConfigScreen::new))))));
HudRenderCallback.EVENT.register((context, tickDelta) -> {
if (!SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enabled
- || client.options.playerListKey.isPressed()
- || client.player == null
- || commissionList.isEmpty()) {
+ || client.options.playerListKey.isPressed()
+ || client.player == null
+ || commissionList.isEmpty()) {
return;
}
- render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.x, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.y, commissionList);
+ render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.x,
+ SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.y, commissionList);
});
}
public static void render(DrawContext context, int hudX, int hudY, List<Commission> commissions) {
- switch(SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.style) {
+ switch (SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.style) {
case SIMPLE -> renderSimple(context, hudX, hudY, commissions);
case FANCY -> renderFancy(context, hudX, hudY, commissions);
case CLASSIC -> renderClassic(context, hudX, hudY, commissions);
@@ -76,12 +75,12 @@ public class DwarvenHud {
int y = 0;
for (Commission commission : commissions) {
context
- .drawTextWithShadow(client.textRenderer,
- Text.literal(commission.commission + ": ")
- .styled(style -> style.withColor(Formatting.AQUA))
- .append(Text.literal(commission.progression)
- .styled(style -> style.withColor(Formatting.GREEN))),
- hudX + 5, hudY + y + 5, 0xFFFFFFFF);
+ .drawTextWithShadow(client.textRenderer,
+ Text.literal(commission.commission + ": ")
+ .styled(style -> style.withColor(Formatting.AQUA))
+ .append(Text.literal(commission.progression)
+ .styled(style -> style.withColor(Formatting.GREEN))),
+ hudX + 5, hudY + y + 5, 0xFFFFFFFF);
y += 20;
}
}
@@ -91,7 +90,8 @@ public class DwarvenHud {
HudCommsWidget.INSTANCE.update();
HudCommsWidget.INSTANCE.setX(hudX);
HudCommsWidget.INSTANCE.setY(hudY);
- HudCommsWidget.INSTANCE.render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ HudCommsWidget.INSTANCE.render(context,
+ SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground);
}
public static void renderFancy(DrawContext context, int hudX, int hudY, List<Commission> commissions) {
@@ -99,12 +99,14 @@ public class DwarvenHud {
HudCommsWidget.INSTANCE.update();
HudCommsWidget.INSTANCE.setX(hudX);
HudCommsWidget.INSTANCE.setY(hudY);
- HudCommsWidget.INSTANCE.render(context, SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground);
+ HudCommsWidget.INSTANCE.render(context,
+ SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enableBackground);
}
public static void update() {
commissionList = new ArrayList<>();
- if (client.player == null || !SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enabled) return;
+ if (client.player == null || !SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.enabled)
+ return;
client.getNetworkHandler().getPlayerList().forEach(playerListEntry -> {
if (playerListEntry.getDisplayName() != null) {
@@ -120,6 +122,6 @@ public class DwarvenHud {
}
// steamroller tactics to get visibility from outside classes (CommsWidget)
- public static record Commission(String commission, String progression){}
-
+ public record Commission(String commission, String progression) {
+ }
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
index f91ed921..10e62d88 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/dwarven/DwarvenHudConfigScreen.java
@@ -5,7 +5,6 @@ import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import me.xmrvizzy.skyblocker.utils.RenderUtils;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.gui.screen.Screen;
-import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.Text;
import java.awt.*;
@@ -15,8 +14,9 @@ public class DwarvenHudConfigScreen extends Screen {
private int hudX = SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.x;
private int hudY = SkyblockerConfig.get().locations.dwarvenMines.dwarvenHud.y;
- protected DwarvenHudConfigScreen(Text title) {
- super(title);
+
+ protected DwarvenHudConfigScreen() {
+ super(Text.of("Dwarven HUD Config"));
}
@Override
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemFixerUpper.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemFixerUpper.java
index d8ad3a89..cc7b216c 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemFixerUpper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemFixerUpper.java
@@ -1,39 +1,45 @@
package me.xmrvizzy.skyblocker.skyblock.itemlist;
-import net.minecraft.item.Items;
-// import net.minecraft.registry.Registry;
-import net.minecraft.registry.Registries;
-import net.minecraft.util.Identifier;
import java.util.Map;
public class ItemFixerUpper {
- private final static Map<String, String> MAPPING = Map.ofEntries(
- Map.entry("minecraft:golden_rail", "minecraft:powered_rail"),
- Map.entry("minecraft:lit_pumpkin", "minecraft:jack_o_lantern"),
- Map.entry("minecraft:snow_layer", "minecraft:snow"),
- Map.entry("minecraft:hardened_clay", "minecraft:terracotta"),
- Map.entry("minecraft:speckled_melon", "minecraft:glistering_melon_slice"),
- Map.entry("minecraft:mob_spawner", "minecraft:spawner"),
- Map.entry("minecraft:brick_block", "minecraft:bricks"),
- Map.entry("minecraft:deadbush", "minecraft:dead_bush"),
- Map.entry("minecraft:slime", "minecraft:slime_block"),
- Map.entry("minecraft:melon_block", "minecraft:melon"),
- Map.entry("minecraft:reeds", "minecraft:sugar_cane"),
- Map.entry("minecraft:yellow_flower", "minecraft:dandelion"),
- Map.entry("minecraft:firework_charge", "minecraft:firework_star"),
- Map.entry("minecraft:noteblock", "minecraft:note_block"),
- Map.entry("minecraft:web", "minecraft:cobweb"),
- Map.entry("minecraft:fireworks", "minecraft:firework_rocket"),
- Map.entry("minecraft:netherbrick", "minecraft:nether_brick"),
- Map.entry("minecraft:stained_hardened_clay", "minecraft:terracotta"),
- Map.entry("minecraft:quartz_ore", "minecraft:nether_quartz_ore"),
- Map.entry("minecraft:tallgrass", "minecraft:grass"),
- Map.entry("minecraft:stone_slab2", "minecraft:red_sandstone_slab"),
- Map.entry("minecraft:waterlily", "minecraft:lily_pad"),
- Map.entry("minecraft:stone_stairs", "minecraft:cobblestone_stairs")
- );
+ private final static String[] ANVIL_VARIANTS = {
+ "minecraft:anvil",
+ "minecraft:chipped_anvil",
+ "minecraft:damaged_anvil"
+ };
+
+ private final static String[] COAL_VARIANTS = {
+ "minecraft:coal",
+ "minecraft:charcoal"
+ };
- private final static String[] DYE_COLORS = {
+ private final static String[] COBBLESTONE_WALL_VARIANTS = {
+ "minecraft:cobblestone_wall",
+ "minecraft:mossy_cobblestone_wall"
+ };
+
+ private final static String[] COOKED_FISH_VARIANTS = {
+ "minecraft:cooked_cod",
+ "minecraft:cooked_salmon"
+ };
+
+ private final static String[] DIRT_VARIANTS = {
+ "minecraft:dirt",
+ "minecraft:coarse_dirt",
+ "minecraft:podzol"
+ };
+
+ private final static String[] DOUBLE_PLANT_VARIANTS = {
+ "minecraft:sunflower",
+ "minecraft:lilac",
+ "minecraft:tall_grass",
+ "minecraft:large_fern",
+ "minecraft:rose_bush",
+ "minecraft:peony"
+ };
+
+ private final static String[] DYE_VARIANTS = {
"minecraft:ink_sac",
"minecraft:red_dye",
"minecraft:green_dye",
@@ -52,39 +58,55 @@ public class ItemFixerUpper {
"minecraft:bone_meal"
};
- private final static String[] BLOCK_COLORS = {
- "white_",
- "orange_",
- "magenta_",
- "light_blue_",
- "yellow_",
- "lime_",
- "pink_",
- "gray_",
- "light_gray_",
- "cyan_",
- "purple_",
- "blue_",
- "brown_",
- "green_",
- "red_",
- "black_"
- };
-
- private final static String[] TREE_VARIANTS = {
- "oak_",
- "spruce_",
- "birch_",
- "jungle_",
- "acacia_",
- "dark_oak_"
- };
-
- private final static String[] STONE_BRICK_VARIANTS = {
- "minecraft:stone_bricks",
- "minecraft:mossy_stone_bricks",
- "minecraft:cracked_stone_bricks",
- "minecraft:chiseled_stone_bricks"
+ private final static String[] FISH_VARIANTS = {
+ "minecraft:cod",
+ "minecraft:salmon",
+ "minecraft:tropical_fish",
+ "minecraft:pufferfish"
+ };
+
+ private final static String[] GOLDEN_APPLE_VARIANTS = {
+ "minecraft:golden_apple",
+ "minecraft:enchanted_golden_apple"
+ };
+
+ private final static String[] LOG_VARIANTS = {
+ "minecraft:oak_log",
+ "minecraft:spruce_log",
+ "minecraft:birch_log",
+ "minecraft:jungle_log",
+ "minecraft:oak_wood",
+ "minecraft:spruce_wood",
+ "minecraft:birch_wood",
+ "minecraft:jungle_wood",
+ };
+
+ private final static String[] LOG2_VARIANTS = {
+ "minecraft:acacia_log",
+ "minecraft:dark_oak_log",
+ "minecraft:acacia_wood",
+ "minecraft:dark_oak_wood"
+ };
+
+ private final static String[] MONSTER_EGG_VARIANTS = {
+ "minecraft:infested_stone",
+ "minecraft:infested_cobblestone",
+ "minecraft:infested_stone_bricks",
+ "minecraft:infested_mossy_stone_bricks",
+ "minecraft:infested_cracked_stone_bricks",
+ "minecraft:infested_chiseled_stone_bricks"
+ };
+
+ private final static String[] PRISMARINE_VARIANTS = {
+ "minecraft:prismarine",
+ "minecraft:prismarine_bricks",
+ "minecraft:dark_prismarine"
+ };
+
+ private final static String[] QUARTZ_BLOCK_VARIANTS = {
+ "minecraft:quartz_block",
+ "minecraft:chiseled_quartz_block",
+ "minecraft:quartz_pillar"
};
private final static String[] RED_FLOWER_VARIANTS = {
@@ -99,45 +121,11 @@ public class ItemFixerUpper {
"minecraft:oxeye_daisy"
};
- private final static String[] DOUBLE_PLANT_VARIANTS = {
- "minecraft:sunflower",
- "minecraft:lilac",
- "minecraft:tall_grass",
- "minecraft:large_fern",
- "minecraft:rose_bush",
- "minecraft:peony"
+ private final static String[] SAND_VARIANTS = {
+ "minecraft:sand",
+ "minecraft:red_sand"
};
- private final static Map<Integer, String> SPAWN_EGG_VARIANTS = Map.ofEntries(
- Map.entry(50, "minecraft:creeper_spawn_egg"),
- Map.entry(51, "minecraft:skeleton_spawn_egg"),
- Map.entry(52, "minecraft:spider_spawn_egg"),
- Map.entry(54, "minecraft:zombie_spawn_egg"),
- Map.entry(55, "minecraft:slime_spawn_egg"),
- Map.entry(56, "minecraft:ghast_spawn_egg"),
- Map.entry(57, "minecraft:zombified_piglin_spawn_egg"),
- Map.entry(58, "minecraft:enderman_spawn_egg"),
- Map.entry(59, "minecraft:cave_spider_spawn_egg"),
- Map.entry(60, "minecraft:silverfish_spawn_egg"),
- Map.entry(61, "minecraft:blaze_spawn_egg"),
- Map.entry(62, "minecraft:magma_cube_spawn_egg"),
- Map.entry(65, "minecraft:bat_spawn_egg"),
- Map.entry(66, "minecraft:witch_spawn_egg"),
- Map.entry(67, "minecraft:endermite_spawn_egg"),
- Map.entry(68, "minecraft:guardian_spawn_egg"),
- Map.entry(90, "minecraft:pig_spawn_egg"),
- Map.entry(91, "minecraft:sheep_spawn_egg"),
- Map.entry(92, "minecraft:cow_spawn_egg"),
- Map.entry(93, "minecraft:chicken_spawn_egg"),
- Map.entry(94, "minecraft:squid_spawn_egg"),
- Map.entry(95, "minecraft:wolf_spawn_egg"),
- Map.entry(96, "minecraft:mooshroom_spawn_egg"),
- Map.entry(98, "minecraft:ocelot_spawn_egg"),
- Map.entry(100, "minecraft:horse_spawn_egg"),
- Map.entry(101, "minecraft:rabbit_spawn_egg"),
- Map.entry(120, "minecraft:villager_spawn_egg")
- );
-
private final static String[] SKULL_VARIANTS = {
"minecraft:skeleton_skull",
"minecraft:wither_skeleton_skull",
@@ -146,16 +134,9 @@ public class ItemFixerUpper {
"minecraft:creeper_head"
};
- private final static String[] FISH_VARIANTS = {
- "minecraft:cod",
- "minecraft:salmon",
- "minecraft:tropical_fish",
- "minecraft:pufferfish"
- };
-
- private final static String[] COOKED_FISH_VARIANTS = {
- "minecraft:cooked_cod",
- "minecraft:cooked_salmon"
+ private final static String[] SPONGE_VARIANTS = {
+ "minecraft:sponge",
+ "minecraft:wet_sponge"
};
private final static String[] STONE_VARIANTS = {
@@ -171,7 +152,7 @@ public class ItemFixerUpper {
private final static String[] STONE_SLAB_VARIANTS = {
"minecraft:smooth_stone_slab",
"minecraft:sandstone_slab",
- "minecraft:barrier", // doesn't exist
+ "minecraft:petrified_oak_slab",
"minecraft:cobblestone_slab",
"minecraft:brick_slab",
"minecraft:stone_brick_slab",
@@ -179,63 +160,182 @@ public class ItemFixerUpper {
"minecraft:quartz_slab"
};
- private final static String[] COBBLESTONE_WALL_VARIANTS = {
- "minecraft:cobblestone_wall",
- "minecraft:mossy_cobblestone_wall"
+ private final static String[] STONEBRICK_VARIANTS = {
+ "minecraft:stone_bricks",
+ "minecraft:mossy_stone_bricks",
+ "minecraft:cracked_stone_bricks",
+ "minecraft:chiseled_stone_bricks"
};
- private final static String[] DIRT_VARIANTS = {
- "minecraft:dirt",
- "minecraft:coarse_dirt",
- "minecraft:podzol"
+ private final static String[] TALLGRASS_VARIANTS = {
+ "minecraft:dead_bush",
+ "minecraft:grass",
+ "minecraft:fern"
};
- private final static String[] SPONGE_VARIANTS = {
- "minecraft:sponge",
- "minecraft:wet_sponge"
+ private final static Map<Integer, String> SPAWN_EGG_VARIANTS = Map.ofEntries(
+ //This entry 0 is technically not right but Hypixel decided to make it polar bear so well we use that
+ Map.entry(0, "minecraft:polar_bear_spawn_egg"),
+ Map.entry(50, "minecraft:creeper_spawn_egg"),
+ Map.entry(51, "minecraft:skeleton_spawn_egg"),
+ Map.entry(52, "minecraft:spider_spawn_egg"),
+ Map.entry(54, "minecraft:zombie_spawn_egg"),
+ Map.entry(55, "minecraft:slime_spawn_egg"),
+ Map.entry(56, "minecraft:ghast_spawn_egg"),
+ Map.entry(57, "minecraft:zombified_piglin_spawn_egg"),
+ Map.entry(58, "minecraft:enderman_spawn_egg"),
+ Map.entry(59, "minecraft:cave_spider_spawn_egg"),
+ Map.entry(60, "minecraft:silverfish_spawn_egg"),
+ Map.entry(61, "minecraft:blaze_spawn_egg"),
+ Map.entry(62, "minecraft:magma_cube_spawn_egg"),
+ Map.entry(65, "minecraft:bat_spawn_egg"),
+ Map.entry(66, "minecraft:witch_spawn_egg"),
+ Map.entry(67, "minecraft:endermite_spawn_egg"),
+ Map.entry(68, "minecraft:guardian_spawn_egg"),
+ Map.entry(90, "minecraft:pig_spawn_egg"),
+ Map.entry(91, "minecraft:sheep_spawn_egg"),
+ Map.entry(92, "minecraft:cow_spawn_egg"),
+ Map.entry(93, "minecraft:chicken_spawn_egg"),
+ Map.entry(94, "minecraft:squid_spawn_egg"),
+ Map.entry(95, "minecraft:wolf_spawn_egg"),
+ Map.entry(96, "minecraft:mooshroom_spawn_egg"),
+ Map.entry(98, "minecraft:ocelot_spawn_egg"),
+ Map.entry(100, "minecraft:horse_spawn_egg"),
+ Map.entry(101, "minecraft:rabbit_spawn_egg"),
+ Map.entry(120, "minecraft:villager_spawn_egg")
+ );
+
+ private final static String[] SANDSTONE_VARIANTS = {
+ ":",
+ ":chiseled_",
+ ":cut_"
};
- private final static String[] PRISMARINE_VARIANTS = {
- "minecraft:prismarine",
- "minecraft:prismarine_bricks",
- "minecraft:dark_prismarine"
+ private final static String[] COLOR_VARIANTS = {
+ ":white_",
+ ":orange_",
+ ":magenta_",
+ ":light_blue_",
+ ":yellow_",
+ ":lime_",
+ ":pink_",
+ ":gray_",
+ ":light_gray_",
+ ":cyan_",
+ ":purple_",
+ ":blue_",
+ ":brown_",
+ ":green_",
+ ":red_",
+ ":black_"
+ };
+
+ private final static String[] WOOD_VARIANTS = {
+ ":oak_",
+ ":spruce_",
+ ":birch_",
+ ":jungle_",
+ ":acacia_",
+ ":dark_oak_"
};
- // TODO: map potions to their correct colors
+ //this is the map of all renames
+ private final static Map<String, String> RENAMED = Map.ofEntries(
+ Map.entry("minecraft:bed", "minecraft:red_bed"),
+ Map.entry("minecraft:boat", "minecraft:oak_boat"),
+ Map.entry("minecraft:brick_block", "minecraft:bricks"),
+ Map.entry("minecraft:deadbush", "minecraft:dead_bush"),
+ Map.entry("minecraft:fence_gate", "minecraft:oak_fence_gate"),
+ Map.entry("minecraft:fence", "minecraft:oak_fence"),
+ Map.entry("minecraft:firework_charge", "minecraft:firework_star"),
+ Map.entry("minecraft:fireworks", "minecraft:firework_rocket"),
+ Map.entry("minecraft:golden_rail", "minecraft:powered_rail"),
+ Map.entry("minecraft:grass", "minecraft:grass_block"),
+ Map.entry("minecraft:hardened_clay", "minecraft:terracotta"),
+ Map.entry("minecraft:lit_pumpkin", "minecraft:jack_o_lantern"),
+ Map.entry("minecraft:melon_block", "minecraft:melon"),
+ Map.entry("minecraft:melon", "minecraft:melon_slice"),
+ Map.entry("minecraft:mob_spawner", "minecraft:spawner"),
+ Map.entry("minecraft:nether_brick", "minecraft:nether_bricks"),
+ Map.entry("minecraft:netherbrick", "minecraft:nether_brick"),
+ Map.entry("minecraft:noteblock", "minecraft:note_block"),
+ Map.entry("minecraft:piston_extension", "minecraft:moving_piston"),
+ Map.entry("minecraft:portal", "minecraft:nether_portal"),
+ Map.entry("minecraft:pumpkin", "minecraft:carved_pumpkin"),
+ Map.entry("minecraft:quartz_ore", "minecraft:nether_quartz_ore"),
+ Map.entry("minecraft:record_11", "minecraft:music_disc_11"),
+ Map.entry("minecraft:record_13", "minecraft:music_disc_13"),
+ Map.entry("minecraft:record_blocks", "minecraft:music_disc_blocks"),
+ Map.entry("minecraft:record_cat", "minecraft:music_disc_cat"),
+ Map.entry("minecraft:record_chirp", "minecraft:music_disc_chirp"),
+ Map.entry("minecraft:record_far", "minecraft:music_disc_far"),
+ Map.entry("minecraft:record_mall", "minecraft:music_disc_mall"),
+ Map.entry("minecraft:record_mellohi", "minecraft:music_disc_mellohi"),
+ Map.entry("minecraft:record_stal", "minecraft:music_disc_stal"),
+ Map.entry("minecraft:record_strad", "minecraft:music_disc_strad"),
+ Map.entry("minecraft:record_wait", "minecraft:music_disc_wait"),
+ Map.entry("minecraft:record_ward", "minecraft:music_disc_ward"),
+ Map.entry("minecraft:red_nether_brick", "minecraft:red_nether_bricks"),
+ Map.entry("minecraft:reeds", "minecraft:sugar_cane"),
+ Map.entry("minecraft:sign", "minecraft:oak_sign"),
+ Map.entry("minecraft:slime", "minecraft:slime_block"),
+ Map.entry("minecraft:snow_layer", "minecraft:snow"),
+ Map.entry("minecraft:snow", "minecraft:snow_block"),
+ Map.entry("minecraft:speckled_melon", "minecraft:glistering_melon_slice"),
+ Map.entry("minecraft:stone_slab2", "minecraft:red_sandstone_slab"),
+ Map.entry("minecraft:stone_stairs", "minecraft:cobblestone_stairs"),
+ Map.entry("minecraft:trapdoor", "minecraft:oak_trapdoor"),
+ Map.entry("minecraft:waterlily", "minecraft:lily_pad"),
+ Map.entry("minecraft:web", "minecraft:cobweb"),
+ Map.entry("minecraft:wooden_button", "minecraft:oak_button"),
+ Map.entry("minecraft:wooden_door", "minecraft:oak_door"),
+ Map.entry("minecraft:wooden_pressure_plate", "minecraft:oak_pressure_plate"),
+ Map.entry("minecraft:yellow_flower", "minecraft:dandelion")
+ );
+
+ //TODO : Add mushroom block variants
+ //i'll do it later because it isn't used and unlike the other, it's not just a rename or a separate, it's a separate and a merge
public static String convertItemId(String id, int damage) {
- if (id.equals("minecraft:dye")) return DYE_COLORS[damage];
- if (id.equals("minecraft:log2")) return "minecraft:" + TREE_VARIANTS[damage + 4] + "log";
- if (id.equals("minecraft:leaves2")) return "minecraft:" + TREE_VARIANTS[damage + 4] + "leaves";
- if (id.equals("minecraft:stonebrick")) return STONE_BRICK_VARIANTS[damage];
- if (id.equals("minecraft:red_flower")) return RED_FLOWER_VARIANTS[damage];
- if (id.equals("minecraft:double_plant")) return DOUBLE_PLANT_VARIANTS[damage];
- if (id.equals("minecraft:spawn_egg")) return SPAWN_EGG_VARIANTS.getOrDefault(damage, "minecraft:ghast_spawn_egg");
- if (id.equals("minecraft:banner")) return "minecraft:" + BLOCK_COLORS[15 - damage] + "banner";
- if (id.equals("minecraft:skull")) return SKULL_VARIANTS[damage];
- if (id.equals("minecraft:fish")) return FISH_VARIANTS[damage];
- if (id.equals("minecraft:cooked_fish")) return COOKED_FISH_VARIANTS[damage];
- if (id.equals("minecraft:stone")) return STONE_VARIANTS[damage];
- if (id.equals("minecraft:stone_slab")) return STONE_SLAB_VARIANTS[damage];
- if (id.equals("minecraft:cobblestone_wall")) return COBBLESTONE_WALL_VARIANTS[damage];
- if (id.equals("minecraft:dirt")) return DIRT_VARIANTS[damage];
- if (id.equals("minecraft:sponge")) return SPONGE_VARIANTS[damage];
- if (id.equals("minecraft:prismarine")) return PRISMARINE_VARIANTS[damage];
-
- id = MAPPING.getOrDefault(id, id);
- // if (Registry.ITEM.get(new Identifier(id)).equals(Items.AIR)) {
- if (Registries.ITEM.get(new Identifier(id)).equals(Items.AIR)) {
- String shortId = id.split(":")[1];
- // if (damage < BLOCK_COLORS.length && !Registry.ITEM.get(new Identifier("minecraft:" + BLOCK_COLORS[damage] + shortId)).equals(Items.AIR))
- if (damage < BLOCK_COLORS.length && !Registries.ITEM.get(new Identifier("minecraft:" + BLOCK_COLORS[damage] + shortId)).equals(Items.AIR))
- return "minecraft:" + BLOCK_COLORS[damage] + shortId;
- // if (damage < TREE_VARIANTS.length && !Registry.ITEM.get(new Identifier("minecraft:" + TREE_VARIANTS[damage] + shortId)).equals(Items.AIR))
- if (damage < TREE_VARIANTS.length && !Registries.ITEM.get(new Identifier("minecraft:" + TREE_VARIANTS[damage] + shortId)).equals(Items.AIR))
- return "minecraft:" + TREE_VARIANTS[damage] + shortId;
-
- if (id.contains("wooden_")) return id.replaceFirst("wooden_", TREE_VARIANTS[damage]);
- if (id.contains("minecraft:record")) return id.replaceFirst("minecraft:record", "minecraft:music_disc");
- }
- return id;
+ return switch (id) {
+ //all the case are simple separate
+ case "minecraft:anvil" -> ANVIL_VARIANTS[damage];
+ case "minecraft:coal" -> COAL_VARIANTS[damage];
+ case "minecraft:cobblestone_wall" -> COBBLESTONE_WALL_VARIANTS[damage];
+ case "minecraft:cooked_fish" -> COOKED_FISH_VARIANTS[damage];
+ case "minecraft:dirt" -> DIRT_VARIANTS[damage];
+ case "minecraft:double_plant" -> DOUBLE_PLANT_VARIANTS[damage];
+ case "minecraft:dye" -> DYE_VARIANTS[damage];
+ case "minecraft:fish" -> FISH_VARIANTS[damage];
+ case "minecraft:golden_apple" -> GOLDEN_APPLE_VARIANTS[damage];
+ case "minecraft:log" -> LOG_VARIANTS[damage];
+ case "minecraft:log2" -> LOG2_VARIANTS[damage];
+ case "minecraft:monster_egg" -> MONSTER_EGG_VARIANTS[damage];
+ case "minecraft:prismarine" -> PRISMARINE_VARIANTS[damage];
+ case "minecraft:quartz_block" -> QUARTZ_BLOCK_VARIANTS[damage];
+ case "minecraft:red_flower" -> RED_FLOWER_VARIANTS[damage];
+ case "minecraft:sand" -> SAND_VARIANTS[damage];
+ case "minecraft:skull" -> SKULL_VARIANTS[damage];
+ case "minecraft:sponge" -> SPONGE_VARIANTS[damage];
+ case "minecraft:stone" -> STONE_VARIANTS[damage];
+ case "minecraft:stone_slab" -> STONE_SLAB_VARIANTS[damage];
+ case "minecraft:stonebrick" -> STONEBRICK_VARIANTS[damage];
+ case "minecraft:tallgrass" -> TALLGRASS_VARIANTS[damage];
+ //we use a Map from int to str instead of an array because numbers are not consecutive
+ case "minecraft:spawn_egg" -> SPAWN_EGG_VARIANTS.get(damage);
+ //when we use the generalized variant we need to replaceFirst
+ case "minecraft:sandstone", "minecraft:red_sandstone" -> id.replaceFirst(":", SANDSTONE_VARIANTS[damage]);
+ //to use the general color variants we need to reverse the order because Minecraft decided so for some reason
+ case "minecraft:banner" -> id.replaceFirst(":", COLOR_VARIANTS[15 - damage]);
+ case "minecraft:carpet", "minecraft:stained_glass", "minecraft:stained_glass_pane", "minecraft:wool" -> id.replaceFirst(":", COLOR_VARIANTS[damage]);
+ //for the terracotta we replace the whole name by the color and append "terracotta" at the end
+ case "minecraft:stained_hardened_clay" -> id.replaceFirst(":stained_hardened_clay", COLOR_VARIANTS[damage]) + "terracotta";
+ //for the wooden slab we need to remove the "wooden_" prefix, but otherwise it's the same, so I just combined them anyway
+ case "minecraft:leaves", "minecraft:planks", "minecraft:sapling", "minecraft:wooden_slab" -> id.replaceFirst(":(?:wooden_)?", WOOD_VARIANTS[damage]);
+ //here we replace the 2 by nothing to remove it as it's not needed anymore
+ case "minecraft:leaves2" -> id.replaceFirst(":", WOOD_VARIANTS[damage + 4]).replaceFirst("2", "");
+ //the default case is just a rename or no change
+ default -> RENAMED.getOrDefault(id, id);
+ };
}
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java
index 3a1f91d3..04dc6820 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/itemlist/ItemListWidget.java
@@ -1,7 +1,7 @@
package me.xmrvizzy.skyblocker.skyblock.itemlist;
import com.mojang.blaze3d.systems.RenderSystem;
-import me.xmrvizzy.skyblocker.mixin.RecipeBookWidgetAccessor;
+import me.xmrvizzy.skyblocker.mixin.accessor.RecipeBookWidgetAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
@@ -15,7 +15,7 @@ import net.minecraft.screen.AbstractRecipeScreenHandler;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
-@Environment(value= EnvType.CLIENT)
+@Environment(value = EnvType.CLIENT)
public class ItemListWidget extends RecipeBookWidget implements Drawable, Selectable {
private int parentWidth;
private int parentHeight;
@@ -23,10 +23,12 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select
private TextFieldWidget searchField;
private SearchResultsWidget results;
- public ItemListWidget() { super(); }
+ public ItemListWidget() {
+ super();
+ }
public void updateSearchResult() {
- this.results.updateSearchResult(((RecipeBookWidgetAccessor)this).getSearchText());
+ this.results.updateSearchResult(((RecipeBookWidgetAccessor) this).getSearchText());
}
@Override
@@ -35,7 +37,7 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select
this.parentWidth = parentWidth;
this.parentHeight = parentHeight;
this.leftOffset = narrow ? 0 : 86;
- this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField();
+ this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField();
int x = (this.parentWidth - 147) / 2 - this.leftOffset;
int y = (this.parentHeight - 166) / 2;
if (ItemRegistry.filesImported) {
@@ -48,14 +50,14 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select
public void render(DrawContext context, int mouseX, int mouseY, float delta) {
if (this.isOpen()) {
MatrixStack matrices = context.getMatrices();
- matrices.push();
+ matrices.push();
matrices.translate(0.0D, 0.0D, 100.0D);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
- this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField();
+ this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField();
int i = (this.parentWidth - 147) / 2 - this.leftOffset;
int j = (this.parentHeight - 166) / 2;
context.drawTexture(TEXTURE, i, j, 1, 1, 147, 166);
- this.searchField = ((RecipeBookWidgetAccessor)this).getSearchField();
+ this.searchField = ((RecipeBookWidgetAccessor) this).getSearchField();
if (!ItemRegistry.filesImported && !this.searchField.isFocused() && this.searchField.getText().isEmpty()) {
Text hintText = (Text.literal("Loading...")).formatted(Formatting.ITALIC).formatted(Formatting.GRAY);
@@ -66,7 +68,7 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select
} else {
this.searchField.render(context, mouseX, mouseY, delta);
}
- if (ItemRegistry.filesImported){
+ if (ItemRegistry.filesImported) {
if (results == null) {
int x = (this.parentWidth - 147) / 2 - this.leftOffset;
int y = (this.parentHeight - 166) / 2;
@@ -88,15 +90,15 @@ public class ItemListWidget extends RecipeBookWidget implements Drawable, Select
@Override
public boolean mouseClicked(double mouseX, double mouseY, int button) {
- if (this.isOpen() && !this.client.player.isSpectator() && ItemRegistry.filesImported && results != null) {
- if (this.searchField != null && this.searchField.mouseClicked(mouseX, mouseY, button)) {
+ if (this.isOpen() && this.client.player != null && !this.client.player.isSpectator() && ItemRegistry.filesImported && this.searchField != null && results != null) {
+ if (this.searchField.mouseClicked(mouseX, mouseY, button)) {
this.results.closeRecipeView();
this.searchField.setFocused(true);
return true;
- } else
- this.searchField.setFocused(false);
+ } else {
+ this.searchField.setFocused(false);
return this.results.mouseClicked(mouseX, mouseY, button);
- } else
- return false;
+ }
+ } else return false;
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java
index c02463a3..d9e97976 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/quicknav/QuickNavButton.java
@@ -3,7 +3,7 @@ package me.xmrvizzy.skyblocker.skyblock.quicknav;
import com.mojang.blaze3d.systems.RenderSystem;
import me.xmrvizzy.skyblocker.SkyblockerMod;
-import me.xmrvizzy.skyblocker.mixin.HandledScreenAccessor;
+import me.xmrvizzy.skyblocker.mixin.accessor.HandledScreenAccessor;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
@@ -19,7 +19,6 @@ import net.minecraft.util.Identifier;
@Environment(value=EnvType.CLIENT)
public class QuickNavButton extends ClickableWidget {
- private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
private static final Identifier BUTTON_TEXTURE = new Identifier("textures/gui/container/creative_inventory/tabs.png");
private final int index;
@@ -42,12 +41,9 @@ public class QuickNavButton extends ClickableWidget {
if (screen instanceof HandledScreen<?> handledScreen) {
int x = ((HandledScreenAccessor)handledScreen).getX();
int y = ((HandledScreenAccessor)handledScreen).getY();
- int w = ((HandledScreenAccessor)handledScreen).getBackgroundWidth();
int h = ((HandledScreenAccessor)handledScreen).getBackgroundHeight();
if (h > 166) --h; // why is this even a thing
- // this.x = x + this.index % 6 * 28 + 4;
this.setX(x + this.index % 6 * 26 + 4);
- // this.y = this.index < 6 ? y - 28 : y + h - 4;
this.setY(this.index < 6 ? y - 26 : y + h - 4);
this.u = 26;
this.v = (index < 6 ? 0 : 64) + (toggled ? 32 : 0);
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/rift/HealingMelonIndicator.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/rift/HealingMelonIndicator.java
index fed34796..aa730c31 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/rift/HealingMelonIndicator.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/rift/HealingMelonIndicator.java
@@ -12,12 +12,12 @@ import net.minecraft.util.Formatting;
public class HealingMelonIndicator {
private static final Title title = new Title("skyblocker.rift.healNow", Formatting.DARK_RED);
- public static void updateHealth(MinecraftClient client) {
+ public static void updateHealth() {
if (!SkyblockerConfig.get().slayer.vampireSlayer.enableHealingMelonIndicator || !Utils.isOnSkyblock() || !Utils.isInTheRift() || !Utils.getLocation().contains("Stillgore Château")) {
TitleContainer.removeTitle(title);
return;
}
- ClientPlayerEntity player = client.player;
+ ClientPlayerEntity player = MinecraftClient.getInstance().player;
if (player != null && player.getHealth() <= SkyblockerConfig.get().slayer.vampireSlayer.healingMelonHealthThreshold * 2F) {
RenderHelper.displayInTitleContainerAndPlaySound(title);
} else {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java
new file mode 100644
index 00000000..44077b3e
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/Shortcuts.java
@@ -0,0 +1,206 @@
+package me.xmrvizzy.skyblocker.skyblock.shortcut;
+
+import com.google.gson.JsonObject;
+import com.google.gson.reflect.TypeToken;
+import com.mojang.brigadier.Command;
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import me.xmrvizzy.skyblocker.SkyblockerMod;
+import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
+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;
+import net.fabricmc.fabric.api.client.message.v1.ClientSendMessageEvents;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.command.CommandRegistryAccess;
+import net.minecraft.text.Text;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.*;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.argument;
+import static net.fabricmc.fabric.api.client.command.v2.ClientCommandManager.literal;
+
+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();
+ @Nullable
+ private static CompletableFuture<Void> shortcutsLoaded;
+ public static final Map<String, String> commands = new HashMap<>();
+ public static final Map<String, String> commandArgs = new HashMap<>();
+
+ public static boolean isShortcutsLoaded() {
+ return shortcutsLoaded != null && shortcutsLoaded.isDone();
+ }
+
+ public static void init() {
+ loadShortcuts();
+ ClientLifecycleEvents.CLIENT_STOPPING.register(Shortcuts::saveShortcuts);
+ ClientCommandRegistrationCallback.EVENT.register(Shortcuts::registerCommands);
+ ClientSendMessageEvents.MODIFY_COMMAND.register(Shortcuts::modifyCommand);
+ }
+
+ protected static void loadShortcuts() {
+ if (shortcutsLoaded != null && !isShortcutsLoaded()) {
+ return;
+ }
+ shortcutsLoaded = CompletableFuture.runAsync(() -> {
+ try (BufferedReader reader = new BufferedReader(new FileReader(SHORTCUTS_FILE))) {
+ Type shortcutsType = new TypeToken<Map<String, Map<String, String>>>() {
+ }.getType();
+ Map<String, Map<String, String>> shortcuts = SkyblockerMod.GSON.fromJson(reader, shortcutsType);
+ commands.clear();
+ commandArgs.clear();
+ 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) {
+ registerDefaultShortcuts();
+ LOGGER.warn("[Skyblocker] Shortcuts file not found, using default shortcuts. This is normal when using for the first time.", e);
+ } catch (IOException e) {
+ LOGGER.error("[Skyblocker] Failed to load shortcuts file", e);
+ }
+ });
+ }
+
+ private static void registerDefaultShortcuts() {
+ commands.clear();
+ commandArgs.clear();
+
+ // Skyblock
+ commands.put("/s", "/skyblock");
+ commands.put("/i", "/is");
+ commands.put("/h", "/hub");
+
+ // Dungeon
+ commands.put("/d", "/warp dungeon_hub");
+
+ // Chat channels
+ commands.put("/ca", "/chat all");
+ commands.put("/cp", "/chat party");
+ commands.put("/cg", "/chat guild");
+ commands.put("/co", "/chat officer");
+ commands.put("/cc", "/chat coop");
+
+ // Message
+ commandArgs.put("/m", "/msg");
+
+ // Party
+ commandArgs.put("/pa", "/p accept");
+ commands.put("/pv", "/p leave");
+ commands.put("/pd", "/p disband");
+ commands.put("/rp", "/reparty");
+
+ // Visit
+ commandArgs.put("/v", "/visit");
+ commands.put("/vp", "/visit portalhub");
+ }
+
+ private static void registerMoreDefaultShortcuts() {
+ // Combat
+ commands.put("/spider", "/warp spider");
+ commands.put("/crimson", "/warp nether");
+ commands.put("/end", "/warp end");
+
+ // Mining
+ commands.put("/gold", "/warp gold");
+ commands.put("/cavern", "/warp deep");
+ commands.put("/dwarven", "/warp mines");
+ commands.put("/fo", "/warp forge");
+ commands.put("/ch", "/warp crystals");
+
+ // Foraging & Farming
+ commands.put("/park", "/warp park");
+ commands.put("/barn", "/warp barn");
+ commands.put("/desert", "/warp desert");
+ commands.put("/ga", "/warp garden");
+
+ // Other warps
+ commands.put("/castle", "/warp castle");
+ commands.put("/museum", "/warp museum");
+ commands.put("/da", "/warp da");
+ commands.put("/crypt", "/warp crypt");
+ commands.put("/nest", "/warp nest");
+ commands.put("/magma", "/warp magma");
+ commands.put("/void", "/warp void");
+ commands.put("/drag", "/warp drag");
+ commands.put("/jungle", "/warp jungle");
+ commands.put("/howl", "/warp howl");
+ }
+
+ protected static void saveShortcuts(MinecraftClient client) {
+ 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))) {
+ SkyblockerMod.GSON.toJson(shortcutsJson, writer);
+ LOGGER.info("[Skyblocker] Saved {} command shortcuts and {} command argument shortcuts", commands.size(), commandArgs.size());
+ } catch (IOException e) {
+ LOGGER.error("[Skyblocker] Failed to save shortcuts file", e);
+ }
+ }
+
+ private static void registerCommands(CommandDispatcher<FabricClientCommandSource> dispatcher, CommandRegistryAccess registryAccess) {
+ for (String key : commands.keySet()) {
+ if (key.startsWith("/")) {
+ dispatcher.register(literal(key.substring(1)));
+ }
+ }
+ for (String key : commandArgs.keySet()) {
+ if (key.startsWith("/")) {
+ dispatcher.register(literal(key.substring(1)).then(argument("args", StringArgumentType.greedyString())));
+ }
+ }
+ dispatcher.register(literal(SkyblockerMod.NAMESPACE).then(literal("help").executes(context -> {
+ FabricClientCommandSource source = context.getSource();
+ String status = SkyblockerConfig.get().general.shortcuts.enableShortcuts && SkyblockerConfig.get().general.shortcuts.enableCommandShortcuts ? "§a§l (Enabled)" : "§c§l (Disabled)";
+ source.sendFeedback(Text.of("§e§lSkyblocker §fCommand Shortcuts" + status));
+ if (!isShortcutsLoaded()) {
+ source.sendFeedback(Text.translatable("skyblocker.shortcuts.notLoaded"));
+ } else for (Map.Entry<String, String> command : commands.entrySet()) {
+ source.sendFeedback(Text.of("§7" + command.getKey() + " §f→ §7" + command.getValue()));
+ }
+ status = SkyblockerConfig.get().general.shortcuts.enableShortcuts && SkyblockerConfig.get().general.shortcuts.enableCommandArgShortcuts ? "§a§l (Enabled)" : "§c§l (Disabled)";
+ source.sendFeedback(Text.of("§e§lSkyblocker §fCommand Argument Shortcuts" + status));
+ if (!isShortcutsLoaded()) {
+ source.sendFeedback(Text.translatable("skyblocker.shortcuts.notLoaded"));
+ } else for (Map.Entry<String, String> commandArg : commandArgs.entrySet()) {
+ source.sendFeedback(Text.of("§7" + commandArg.getKey() + " §f→ §7" + commandArg.getValue()));
+ }
+ source.sendFeedback(Text.of("§e§lSkyblocker §fCommands"));
+ for (String command : dispatcher.getSmartUsage(dispatcher.getRoot().getChild(SkyblockerMod.NAMESPACE), source).values()) {
+ source.sendFeedback(Text.of("§7/" + SkyblockerMod.NAMESPACE + " " + command));
+ }
+ return Command.SINGLE_SUCCESS;
+ // Queue the screen or else the screen will be immediately closed after executing this command
+ })).then(literal("shortcuts").executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(ShortcutsConfigScreen::new))));
+ }
+
+ private static String modifyCommand(String command) {
+ if (SkyblockerConfig.get().general.shortcuts.enableShortcuts) {
+ if (!isShortcutsLoaded()) {
+ LOGGER.warn("[Skyblocker] Shortcuts not loaded yet, skipping shortcut for command: {}", command);
+ return command;
+ }
+ command = '/' + command;
+ if (SkyblockerConfig.get().general.shortcuts.enableCommandShortcuts) {
+ command = commands.getOrDefault(command, command);
+ }
+ if (SkyblockerConfig.get().general.shortcuts.enableCommandArgShortcuts) {
+ String[] messageArgs = command.split(" ");
+ for (int i = 0; i < messageArgs.length; i++) {
+ messageArgs[i] = commandArgs.getOrDefault(messageArgs[i], messageArgs[i]);
+ }
+ command = String.join(" ", messageArgs);
+ }
+ return command.substring(1);
+ }
+ return command;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigListWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigListWidget.java
new file mode 100644
index 00000000..f29470bf
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigListWidget.java
@@ -0,0 +1,232 @@
+package me.xmrvizzy.skyblocker.skyblock.shortcut;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.Element;
+import net.minecraft.client.gui.Selectable;
+import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
+import net.minecraft.client.gui.screen.narration.NarrationPart;
+import net.minecraft.client.gui.widget.ElementListWidget;
+import net.minecraft.client.gui.widget.TextFieldWidget;
+import net.minecraft.text.Text;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.stream.Stream;
+
+public class ShortcutsConfigListWidget extends ElementListWidget<ShortcutsConfigListWidget.AbstractShortcutEntry> {
+ private final ShortcutsConfigScreen screen;
+ private final List<Map<String, String>> shortcutMaps = new ArrayList<>();
+
+ public ShortcutsConfigListWidget(MinecraftClient minecraftClient, ShortcutsConfigScreen screen, int width, int height, int top, int bottom, int itemHeight) {
+ super(minecraftClient, width, height, top, bottom, itemHeight);
+ this.screen = screen;
+ ShortcutCategoryEntry commandCategory = new ShortcutCategoryEntry(Shortcuts.commands, "skyblocker.shortcuts.command.target", "skyblocker.shortcuts.command.replacement");
+ if (Shortcuts.isShortcutsLoaded()) {
+ commandCategory.shortcutsMap.keySet().stream().sorted().forEach(commandTarget -> addEntry(new ShortcutEntry(commandCategory, commandTarget)));
+ } else {
+ addEntry(new ShortcutLoadingEntry());
+ }
+ ShortcutCategoryEntry commandArgCategory = new ShortcutCategoryEntry(Shortcuts.commandArgs, "skyblocker.shortcuts.commandArg.target", "skyblocker.shortcuts.commandArg.replacement", "skyblocker.shortcuts.commandArg.tooltip");
+ if (Shortcuts.isShortcutsLoaded()) {
+ commandArgCategory.shortcutsMap.keySet().stream().sorted().forEach(commandArgTarget -> addEntry(new ShortcutEntry(commandArgCategory, commandArgTarget)));
+ } else {
+ addEntry(new ShortcutLoadingEntry());
+ }
+ }
+
+ @Override
+ public int getRowWidth() {
+ return super.getRowWidth() + 100;
+ }
+
+ @Override
+ protected int getScrollbarPositionX() {
+ return super.getScrollbarPositionX() + 50;
+ }
+
+ protected Optional<ShortcutCategoryEntry> getCategory() {
+ if (getSelectedOrNull() instanceof ShortcutCategoryEntry category) {
+ return Optional.of(category);
+ } else if (getSelectedOrNull() instanceof ShortcutEntry shortcutEntry) {
+ return Optional.of(shortcutEntry.category);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public void setSelected(@Nullable ShortcutsConfigListWidget.AbstractShortcutEntry entry) {
+ super.setSelected(entry);
+ screen.updateButtons();
+ }
+
+ protected void addShortcutAfterSelected() {
+ getCategory().ifPresent(category -> children().add(children().indexOf(getSelectedOrNull()) + 1, new ShortcutEntry(category)));
+ }
+
+ @Override
+ protected boolean removeEntry(AbstractShortcutEntry entry) {
+ return super.removeEntry(entry);
+ }
+
+ protected boolean hasChanges() {
+ ShortcutEntry[] notEmptyShortcuts = getNotEmptyShortcuts().toArray(ShortcutEntry[]::new);
+ return notEmptyShortcuts.length != shortcutMaps.stream().mapToInt(Map::size).sum() || Arrays.stream(notEmptyShortcuts).anyMatch(ShortcutEntry::isChanged);
+ }
+
+ protected void saveShortcuts() {
+ shortcutMaps.forEach(Map::clear);
+ getNotEmptyShortcuts().forEach(ShortcutEntry::save);
+ Shortcuts.saveShortcuts(MinecraftClient.getInstance()); // Save shortcuts to disk
+ }
+
+ private Stream<ShortcutEntry> getNotEmptyShortcuts() {
+ return children().stream().filter(ShortcutEntry.class::isInstance).map(ShortcutEntry.class::cast).filter(ShortcutEntry::isNotEmpty);
+ }
+
+ protected static abstract class AbstractShortcutEntry extends ElementListWidget.Entry<AbstractShortcutEntry> {
+ }
+
+ private class ShortcutCategoryEntry extends AbstractShortcutEntry {
+ private final Map<String, String> shortcutsMap;
+ private final Text targetName;
+ private final Text replacementName;
+ @Nullable
+ private final Text tooltip;
+
+ private ShortcutCategoryEntry(Map<String, String> shortcutsMap, String targetName, String replacementName) {
+ this(shortcutsMap, targetName, replacementName, (Text) null);
+ }
+
+ private ShortcutCategoryEntry(Map<String, String> shortcutsMap, String targetName, String replacementName, String tooltip) {
+ this(shortcutsMap, targetName, replacementName, Text.translatable(tooltip));
+ }
+
+ private ShortcutCategoryEntry(Map<String, String> shortcutsMap, String targetName, String replacementName, @Nullable Text tooltip) {
+ this.shortcutsMap = shortcutsMap;
+ this.targetName = Text.translatable(targetName);
+ this.replacementName = Text.translatable(replacementName);
+ this.tooltip = tooltip;
+ shortcutMaps.add(shortcutsMap);
+ addEntry(this);
+ }
+
+ @Override
+ public List<? extends Element> children() {
+ return List.of();
+ }
+
+ @Override
+ public List<? extends Selectable> selectableChildren() {
+ return List.of(new Selectable() {
+ @Override
+ public SelectionType getType() {
+ return SelectionType.HOVERED;
+ }
+
+ @Override
+ public void appendNarrations(NarrationMessageBuilder builder) {
+ builder.put(NarrationPart.TITLE, targetName, replacementName);
+ }
+ });
+ }
+
+ @Override
+ public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
+ context.drawCenteredTextWithShadow(client.textRenderer, targetName, width / 2 - 85, y + 5, 0xFFFFFF);
+ context.drawCenteredTextWithShadow(client.textRenderer, replacementName, width / 2 + 85, y + 5, 0xFFFFFF);
+ if (tooltip != null && isMouseOver(mouseX, mouseY)) {
+ screen.setTooltip(tooltip);
+ }
+ }
+ }
+
+ private class ShortcutLoadingEntry extends AbstractShortcutEntry {
+ private final Text text;
+
+ private ShortcutLoadingEntry() {
+ this.text = Text.translatable("skyblocker.shortcuts.notLoaded");
+ }
+
+ @Override
+ public List<? extends Element> children() {
+ return List.of();
+ }
+
+ @Override
+ public List<? extends Selectable> selectableChildren() {
+ return List.of(new Selectable() {
+ @Override
+ public SelectionType getType() {
+ return SelectionType.HOVERED;
+ }
+
+ @Override
+ public void appendNarrations(NarrationMessageBuilder builder) {
+ builder.put(NarrationPart.TITLE, text);
+ }
+ });
+ }
+
+ @Override
+ public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
+ context.drawCenteredTextWithShadow(client.textRenderer, text, width / 2, y + 5, 0xFFFFFF);
+ }
+ }
+
+ protected class ShortcutEntry extends AbstractShortcutEntry {
+ private final List<TextFieldWidget> children;
+ private final ShortcutCategoryEntry category;
+ private final TextFieldWidget target;
+ private final TextFieldWidget replacement;
+
+ private ShortcutEntry(ShortcutCategoryEntry category) {
+ this(category, "");
+ }
+
+ private ShortcutEntry(ShortcutCategoryEntry category, String targetString) {
+ this.category = category;
+ target = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, width / 2 - 160, 5, 150, 20, category.targetName);
+ replacement = new TextFieldWidget(MinecraftClient.getInstance().textRenderer, width / 2 + 10, 5, 150, 20, category.replacementName);
+ target.setText(targetString);
+ replacement.setText(category.shortcutsMap.getOrDefault(targetString, ""));
+ children = List.of(target, replacement);
+ }
+
+ @Override
+ public String toString() {
+ return target.getText() + " → " + replacement.getText();
+ }
+
+ @Override
+ public List<? extends Element> children() {
+ return children;
+ }
+
+ @Override
+ public List<? extends Selectable> selectableChildren() {
+ return children;
+ }
+
+ private boolean isNotEmpty() {
+ return !target.getText().isEmpty() && !replacement.getText().isEmpty();
+ }
+
+ private boolean isChanged() {
+ return !category.shortcutsMap.containsKey(target.getText()) || !category.shortcutsMap.get(target.getText()).equals(replacement.getText());
+ }
+
+ private void save() {
+ category.shortcutsMap.put(target.getText(), replacement.getText());
+ }
+
+ @Override
+ public void render(DrawContext context, int index, int y, int x, int entryWidth, int entryHeight, int mouseX, int mouseY, boolean hovered, float tickDelta) {
+ target.setY(y);
+ replacement.setY(y);
+ target.render(context, mouseX, mouseY, tickDelta);
+ replacement.render(context, mouseX, mouseY, tickDelta);
+ context.drawCenteredTextWithShadow(client.textRenderer, "→", width / 2, y + 5, 0xFFFFFF);
+ }
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
new file mode 100644
index 00000000..dec23d36
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/shortcut/ShortcutsConfigScreen.java
@@ -0,0 +1,107 @@
+package me.xmrvizzy.skyblocker.skyblock.shortcut;
+
+import net.minecraft.client.gui.DrawContext;
+import net.minecraft.client.gui.screen.ConfirmScreen;
+import net.minecraft.client.gui.screen.Screen;
+import net.minecraft.client.gui.tooltip.Tooltip;
+import net.minecraft.client.gui.widget.ButtonWidget;
+import net.minecraft.client.gui.widget.GridWidget;
+import net.minecraft.client.gui.widget.SimplePositioningWidget;
+import net.minecraft.screen.ScreenTexts;
+import net.minecraft.text.Text;
+
+public class ShortcutsConfigScreen extends Screen {
+
+ private ShortcutsConfigListWidget shortcutsConfigListWidget;
+ private ButtonWidget buttonDelete;
+ private ButtonWidget buttonNew;
+ private ButtonWidget buttonDone;
+ private boolean initialized;
+ private double scrollAmount;
+
+ public ShortcutsConfigScreen() {
+ super(Text.translatable("skyblocker.shortcuts.config"));
+ }
+
+ @Override
+ public void setTooltip(Text tooltip) {
+ super.setTooltip(tooltip);
+ }
+
+ @Override
+ protected void init() {
+ super.init();
+ if (initialized) {
+ shortcutsConfigListWidget.updateSize(width, height, 32, height - 64);
+ } else {
+ shortcutsConfigListWidget = new ShortcutsConfigListWidget(client, this, width, height, 32, height - 64, 25);
+ initialized = true;
+ }
+ addDrawableChild(shortcutsConfigListWidget);
+ GridWidget gridWidget = new GridWidget();
+ gridWidget.getMainPositioner().marginX(5).marginY(2);
+ GridWidget.Adder adder = gridWidget.createAdder(2);
+ buttonDelete = ButtonWidget.builder(Text.translatable("selectServer.delete"), button -> {
+ if (client != null && shortcutsConfigListWidget.getSelectedOrNull() instanceof ShortcutsConfigListWidget.ShortcutEntry shortcutEntry) {
+ scrollAmount = shortcutsConfigListWidget.getScrollAmount();
+ client.setScreen(new ConfirmScreen(this::deleteEntry, Text.translatable("skyblocker.shortcuts.deleteQuestion"), Text.translatable("skyblocker.shortcuts.deleteWarning", shortcutEntry), Text.translatable("selectServer.deleteButton"), ScreenTexts.CANCEL));
+ }
+ }).build();
+ adder.add(buttonDelete);
+ buttonNew = ButtonWidget.builder(Text.translatable("skyblocker.shortcuts.new"), buttonNew -> shortcutsConfigListWidget.addShortcutAfterSelected()).build();
+ adder.add(buttonNew);
+ adder.add(ButtonWidget.builder(ScreenTexts.CANCEL, button -> {
+ if (client != null) {
+ close();
+ }
+ }).build());
+ buttonDone = ButtonWidget.builder(ScreenTexts.DONE, button -> {
+ shortcutsConfigListWidget.saveShortcuts();
+ if (client != null) {
+ close();
+ }
+ }).tooltip(Tooltip.of(Text.translatable("skyblocker.shortcuts.commandSuggestionTooltip"))).build();
+ adder.add(buttonDone);
+ gridWidget.refreshPositions();
+ SimplePositioningWidget.setPos(gridWidget, 0, this.height - 64, this.width, 64);
+ gridWidget.forEachChild(this::addDrawableChild);
+ updateButtons();
+ }
+
+ private void deleteEntry(boolean confirmedAction) {
+ if (client != null) {
+ if (confirmedAction && shortcutsConfigListWidget.getSelectedOrNull() instanceof ShortcutsConfigListWidget.ShortcutEntry shortcutEntry) {
+ shortcutsConfigListWidget.removeEntry(shortcutEntry);
+ }
+ client.setScreen(this); // Re-inits the screen and keeps the old instance of ShortcutsConfigListWidget
+ shortcutsConfigListWidget.setScrollAmount(scrollAmount);
+ }
+ }
+
+ @Override
+ public void render(DrawContext context, int mouseX, int mouseY, float delta) {
+ super.render(context, mouseX, mouseY, delta);
+ context.drawCenteredTextWithShadow(this.textRenderer, this.title, this.width / 2, 16, 0xFFFFFF);
+ }
+
+ @Override
+ public void close() {
+ if (client != null && shortcutsConfigListWidget.hasChanges()) {
+ client.setScreen(new ConfirmScreen(confirmedAction -> {
+ if (confirmedAction) {
+ super.close();
+ } else {
+ client.setScreen(this);
+ }
+ }, Text.translatable("text.cloth-config.quit_config"), Text.translatable("text.cloth-config.quit_config_sure"), Text.translatable("text.cloth-config.quit_discard"), ScreenTexts.CANCEL));
+ } else {
+ super.close();
+ }
+ }
+
+ protected void updateButtons() {
+ buttonDelete.active = Shortcuts.isShortcutsLoaded() && shortcutsConfigListWidget.getSelectedOrNull() instanceof ShortcutsConfigListWidget.ShortcutEntry;
+ buttonNew.active = Shortcuts.isShortcutsLoaded() && shortcutsConfigListWidget.getCategory().isPresent();
+ buttonDone.active = Shortcuts.isShortcutsLoaded();
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
index 5caa190c..30cc242e 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerListMgr.java
@@ -7,7 +7,7 @@ import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import me.xmrvizzy.skyblocker.mixin.PlayerListHudAccessor;
+import me.xmrvizzy.skyblocker.mixin.accessor.PlayerListHudAccessor;
import me.xmrvizzy.skyblocker.utils.Utils;
import net.minecraft.client.MinecraftClient;
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java
index 9b24171a..deadaa7d 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/util/PlayerLocator.java
@@ -26,6 +26,7 @@ public class PlayerLocator {
GARDEN("garden"),
INSTANCED("kuudra"),
THE_RIFT("rift"),
+ DARK_AUCTION("dark_auction"),
UNKNOWN("unknown");
public String internal;
@@ -92,7 +93,9 @@ public class PlayerLocator {
case "Instanced":
return Location.INSTANCED;
case "The Rift":
- return Location.THE_RIFT;
+ return Location.THE_RIFT;
+ case "Dark Auction":
+ return Location.DARK_AUCTION;
default:
return Location.UNKNOWN;
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/CameraPositionWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/CameraPositionWidget.java
new file mode 100644
index 00000000..7e44bc44
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/CameraPositionWidget.java
@@ -0,0 +1,37 @@
+package me.xmrvizzy.skyblocker.skyblock.tabhud.widget;
+
+import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+import net.minecraft.util.math.MathHelper;
+
+public class CameraPositionWidget extends Widget {
+ private static final MutableText TITLE = Text.literal("Camera Pos").formatted(Formatting.DARK_PURPLE,
+ Formatting.BOLD);
+ private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
+
+ public CameraPositionWidget() {
+ super(TITLE, Formatting.DARK_PURPLE.getColorValue());
+ }
+
+ @Override
+ public void updateContent() {
+ double yaw = CLIENT.getCameraEntity().getYaw();
+ double pitch = CLIENT.getCameraEntity().getPitch();
+
+ this.addComponent(
+ new PlainTextComponent(Text.literal("Yaw: " + roundToDecimalPlaces(MathHelper.wrapDegrees(yaw), 3))));
+ this.addComponent(new PlainTextComponent(
+ Text.literal("Pitch: " + roundToDecimalPlaces(MathHelper.wrapDegrees(pitch), 3))));
+
+ }
+
+ // https://stackoverflow.com/a/33889423
+ private static double roundToDecimalPlaces(double value, int decimalPlaces) {
+ double shift = Math.pow(10, decimalPlaces);
+
+ return Math.round(value * shift) / shift;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
new file mode 100644
index 00000000..945fb17c
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/skyblock/tabhud/widget/GardenVisitorsWidget.java
@@ -0,0 +1,30 @@
+package me.xmrvizzy.skyblocker.skyblock.tabhud.widget;
+
+import me.xmrvizzy.skyblocker.skyblock.tabhud.util.PlayerListMgr;
+import me.xmrvizzy.skyblocker.skyblock.tabhud.widget.component.PlainTextComponent;
+import net.minecraft.text.MutableText;
+import net.minecraft.text.Text;
+import net.minecraft.util.Formatting;
+
+public class GardenVisitorsWidget extends Widget {
+ private static final MutableText TITLE = Text.literal("Visitors").formatted(Formatting.DARK_GREEN, Formatting.BOLD);
+
+ public GardenVisitorsWidget() {
+ super(TITLE, Formatting.DARK_GREEN.getColorValue());
+ }
+
+ @Override
+ public void updateContent() {
+ if (PlayerListMgr.textAt(54) == null) {
+ this.addComponent(new PlainTextComponent(Text.literal("No visitors!").formatted(Formatting.GRAY)));
+ return;
+ }
+
+ for (int i = 54; i < 59; i++) {
+ String text = PlayerListMgr.strAt(i);
+ if (text != null)
+ this.addComponent(new PlainTextComponent(Text.literal(text)));
+ }
+
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/FrustumUtils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/FrustumUtils.java
index 9ea90c16..fd8ffdbd 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/FrustumUtils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/FrustumUtils.java
@@ -1,6 +1,6 @@
package me.xmrvizzy.skyblocker.utils;
-import me.xmrvizzy.skyblocker.mixin.AccessorWorldRenderer;
+import me.xmrvizzy.skyblocker.mixin.accessor.WorldRendererAccessor;
import me.xmrvizzy.skyblocker.mixin.accessor.FrustumInvoker;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.Frustum;
@@ -9,7 +9,7 @@ import net.minecraft.util.math.Box;
public class FrustumUtils {
public static Frustum getFrustum() {
- return ((AccessorWorldRenderer) MinecraftClient.getInstance().worldRenderer).getFrustum();
+ return ((WorldRendererAccessor) MinecraftClient.getInstance().worldRenderer).getFrustum();
}
public static boolean isBoxVisible(Box box) {
@@ -17,6 +17,6 @@ public class FrustumUtils {
}
public static boolean isVisible(double minX, double minY, double minZ, double maxX, double maxY, double maxZ) {
- return ((FrustumInvoker) getFrustum()).isVisible(minX, minY, minZ, maxX, maxY, maxZ);
+ return ((FrustumInvoker) getFrustum()).invokeIsVisible(minX, minY, minZ, maxX, maxY, maxZ);
}
} \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
index 6fa93735..a1221549 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderHelper.java
@@ -2,22 +2,29 @@ package me.xmrvizzy.skyblocker.utils;
import me.x150.renderer.render.Renderer3d;
import me.xmrvizzy.skyblocker.mixin.accessor.BeaconBlockEntityRendererInvoker;
+import me.xmrvizzy.skyblocker.utils.culling.OcclusionCulling;
import me.xmrvizzy.skyblocker.utils.title.Title;
import me.xmrvizzy.skyblocker.utils.title.TitleContainer;
import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderContext;
import net.minecraft.client.MinecraftClient;
-import net.minecraft.client.render.block.entity.BeaconBlockEntityRenderer;
+import net.minecraft.client.render.BufferBuilder;
+import net.minecraft.client.render.Camera;
+import net.minecraft.client.render.Tessellator;
+import net.minecraft.client.render.VertexConsumerProvider;
+import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.sound.SoundEvent;
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
-
import java.awt.*;
+import com.mojang.blaze3d.systems.RenderSystem;
+
public class RenderHelper {
private static final Vec3d ONE = new Vec3d(1, 1, 1);
+ private static final int MAX_OVERWORLD_BUILD_HEIGHT = 319;
public static void renderFilledThroughWallsWithBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
renderFilledThroughWalls(context, pos, colorComponents, alpha);
@@ -25,26 +32,40 @@ public class RenderHelper {
}
public static void renderFilledThroughWalls(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
- Renderer3d.renderThroughWalls();
- renderFilled(context, pos, colorComponents, alpha);
- Renderer3d.stopRenderThroughWalls();
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
+ Renderer3d.renderThroughWalls();
+ renderFilled(context, pos, colorComponents, alpha);
+ Renderer3d.stopRenderThroughWalls();
+ }
}
public static void renderFilledIfVisible(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)) {
+ if (OcclusionCulling.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1)) {
renderFilled(context, pos, colorComponents, alpha);
}
}
- public static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
+ private static void renderFilled(WorldRenderContext context, BlockPos pos, float[] colorComponents, float alpha) {
Renderer3d.renderFilled(context.matrixStack(), new Color(colorComponents[0], colorComponents[1], colorComponents[2], alpha), Vec3d.of(pos), ONE);
}
- public static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
- context.matrixStack().push();
- context.matrixStack().translate(pos.getX() - context.camera().getPos().x, pos.getY() - context.camera().getPos().y, pos.getZ() - context.camera().getPos().z);
- BeaconBlockEntityRendererInvoker.renderBeam(context.matrixStack(), context.consumers(), context.tickDelta(), context.world().getTime(), 0, BeaconBlockEntityRenderer.MAX_BEAM_HEIGHT, colorComponents);
- context.matrixStack().pop();
+ private static void renderBeaconBeam(WorldRenderContext context, BlockPos pos, float[] colorComponents) {
+ if (FrustumUtils.isVisible(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, MAX_OVERWORLD_BUILD_HEIGHT, pos.getZ() + 1)) {
+ MatrixStack matrices = context.matrixStack();
+ Vec3d camera = context.camera().getPos();
+
+ matrices.push();
+ matrices.translate(pos.getX() - camera.x, pos.getY() - camera.y, pos.getZ() - camera.z);
+
+ 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);
+
+ consumer.draw();
+ matrices.pop();
+ }
}
public static void displayTitleAndPlaySound(int stayTicks, int fadeOutTicks, String titleKey, Formatting formatting) {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
index 73ad468f..61f79ae1 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/RenderUtils.java
@@ -82,7 +82,7 @@ public class RenderUtils {
e.getZ() - MathHelper.lerp(tickDelta, e.lastRenderZ, e.getZ()));
}
- public static Boolean pointExistsInArea(int x, int y, int x1, int y1, int x2, int y2) {
+ public static boolean pointExistsInArea(int x, int y, int x1, int y1, int x2, int y2) {
return x >= x1 && x <= x2 && y >= y1 && y <= y2;
}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java
index 7b19e284..fbe79ade 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Scheduler.java
@@ -1,5 +1,6 @@
package me.xmrvizzy.skyblocker.utils;
+import com.mojang.brigadier.Command;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
@@ -58,17 +59,9 @@ public class Scheduler {
*
* @param screenSupplier the supplier of the screen to open
*/
- public void queueOpenScreen(Supplier<Screen> screenSupplier) {
- queueOpenScreen(screenSupplier.get());
- }
-
- /**
- * Schedules a screen to open in the next tick. Used in commands to avoid screen immediately closing after the command is executed.
- *
- * @param screen the supplier of the screen to open
- */
- public void queueOpenScreen(Screen screen) {
- MinecraftClient.getInstance().send(() -> MinecraftClient.getInstance().setScreen(screen));
+ public int queueOpenScreen(Supplier<Screen> screenSupplier) {
+ MinecraftClient.getInstance().send(() -> MinecraftClient.getInstance().setScreen(screenSupplier.get()));
+ return Command.SINGLE_SUCCESS;
}
public void tick() {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
index 35dfd368..71e3b44f 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/Utils.java
@@ -29,6 +29,7 @@ import java.util.List;
*/
public class Utils {
private static final String PROFILE_PREFIX = "Profile: ";
+ private static boolean isOnHypixel = false;
private static boolean isOnSkyblock = false;
private static boolean isInDungeons = false;
private static boolean isInjected = false;
@@ -45,6 +46,10 @@ public class Utils {
private static boolean sentLocRaw = false;
private static long lastLocRaw = 0;
+ public static boolean isOnHypixel() {
+ return isOnHypixel;
+ }
+
public static boolean isOnSkyblock() {
return isOnSkyblock;
}
@@ -126,21 +131,35 @@ public class Utils {
String string = sidebar.toString();
if (sidebar.isEmpty()) return;
- if (sidebar.get(0).contains("SKYBLOCK") || sidebar.get(0).contains("SKIBLOCK")) {
- if (!isOnSkyblock) {
- if (!isInjected) {
- isInjected = true;
- ItemTooltipCallback.EVENT.register(PriceInfoTooltip::onInjectTooltip);
+ if (sidebar.get(sidebar.size() - 1).equals("www.hypixel.net")) {
+ if (!isOnHypixel) {
+ isOnHypixel = true;
+ }
+ if (sidebar.get(0).contains("SKYBLOCK") || sidebar.get(0).contains("SKIBLOCK")) {
+ if (!isOnSkyblock) {
+ if (!isInjected) {
+ isInjected = true;
+ ItemTooltipCallback.EVENT.register(PriceInfoTooltip::onInjectTooltip);
+ }
+ isOnSkyblock = true;
+ SkyblockEvents.JOIN.invoker().onSkyblockJoin();
}
- isOnSkyblock = true;
- SkyblockEvents.JOIN.invoker().onSkyblockJoin();
+ } else {
+ leaveSkyblock();
}
- } else if (isOnSkyblock) {
+ isInDungeons = isOnSkyblock && string.contains("The Catacombs");
+ } else if (isOnHypixel) {
+ isOnHypixel = false;
+ leaveSkyblock();
+ }
+ }
+
+ private static void leaveSkyblock() {
+ if (isOnSkyblock) {
isOnSkyblock = false;
isInDungeons = false;
SkyblockEvents.LEAVE.invoker().onSkyblockLeave();
}
- isInDungeons = isOnSkyblock && string.contains("The Catacombs");
}
public static String getLocation() {
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java
new file mode 100644
index 00000000..e9a25fc3
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/OcclusionCulling.java
@@ -0,0 +1,48 @@
+package me.xmrvizzy.skyblocker.utils.culling;
+
+import com.logisticscraft.occlusionculling.OcclusionCullingInstance;
+import com.logisticscraft.occlusionculling.cache.ArrayOcclusionCache;
+import com.logisticscraft.occlusionculling.util.Vec3d;
+
+import me.xmrvizzy.skyblocker.utils.FrustumUtils;
+import net.minecraft.client.MinecraftClient;
+
+public class OcclusionCulling {
+ private static final int TRACING_DISTANCE = 128;
+ private static final MinecraftClient CLIENT = MinecraftClient.getInstance();
+ private static OcclusionCullingInstance instance = null;
+
+ // Reused objects to reduce allocation overhead
+ private static Vec3d cameraPos = new Vec3d(0, 0, 0);
+ private static Vec3d min = new Vec3d(0, 0, 0);
+ private static Vec3d max = new Vec3d(0, 0, 0);
+
+ /**
+ * Initializes the occlusion culling instance
+ */
+ public static void init() {
+ instance = new OcclusionCullingInstance(TRACING_DISTANCE, new WorldProvider(), new ArrayOcclusionCache(TRACING_DISTANCE), 2);
+ }
+
+ private static void updateCameraPos() {
+ var camera = CLIENT.gameRenderer.getCamera().getPos();
+ cameraPos.set(camera.x, camera.y, camera.z);
+ }
+
+ /**
+ * This first checks checks if the bounding box is within the camera's FOV, if
+ * it is then it checks for whether it's occluded or not.
+ *
+ * @return A boolean representing whether the bounding box is fully visible or
+ * not.
+ */
+ public static boolean isVisible(double x1, double y1, double z1, double x2, double y2, double z2) {
+ if (!FrustumUtils.isVisible(x1, y1, z1, x2, y2, z2)) return false;
+
+ updateCameraPos();
+ min.set(x1, y1, z1);
+ max.set(x2, y2, z2);
+
+ return instance.isAABBVisible(min, max, cameraPos);
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java
new file mode 100644
index 00000000..47d92c1f
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/WorldProvider.java
@@ -0,0 +1,29 @@
+package me.xmrvizzy.skyblocker.utils.culling;
+
+import com.logisticscraft.occlusionculling.DataProvider;
+
+import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.world.ClientWorld;
+import net.minecraft.util.math.BlockPos;
+
+public class WorldProvider implements DataProvider {
+ private final static MinecraftClient CLIENT = MinecraftClient.getInstance();
+ private ClientWorld world = null;
+
+ @Override
+ public boolean prepareChunk(int chunkX, int chunkZ) {
+ this.world = CLIENT.world;
+ return this.world != null;
+ }
+
+ @Override
+ public boolean isOpaqueFullCube(int x, int y, int z) {
+ BlockPos pos = new BlockPos(x, y, z);
+ return this.world.getBlockState(pos).isOpaqueFullCube(this.world, pos);
+ }
+
+ @Override
+ public void cleanup() {
+ this.world = null;
+ }
+}
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java
new file mode 100644
index 00000000..c25e7f7a
--- /dev/null
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/culling/package-info.java
@@ -0,0 +1,4 @@
+/**
+ * Package dedicated to occlusion culling utilities
+ */
+package me.xmrvizzy.skyblocker.utils.culling; \ No newline at end of file
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java
index a4e445ee..7b92fff6 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainer.java
@@ -1,6 +1,5 @@
package me.xmrvizzy.skyblocker.utils.title;
-import com.mojang.brigadier.Command;
import me.xmrvizzy.skyblocker.SkyblockerMod;
import me.xmrvizzy.skyblocker.config.SkyblockerConfig;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
@@ -9,7 +8,6 @@ import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.font.TextRenderer;
import net.minecraft.client.gui.DrawContext;
-import net.minecraft.text.Text;
import net.minecraft.util.math.MathHelper;
import java.util.LinkedHashSet;
@@ -31,10 +29,7 @@ public class TitleContainer {
ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> dispatcher.register(ClientCommandManager.literal("skyblocker")
.then(ClientCommandManager.literal("hud")
.then(ClientCommandManager.literal("titleContainer")
- .executes(context -> {
- SkyblockerMod.getInstance().scheduler.queueOpenScreen(new TitleContainerConfigScreen(Text.of("Title Container HUD Config")));
- return Command.SINGLE_SUCCESS;
- })))));
+ .executes(context -> SkyblockerMod.getInstance().scheduler.queueOpenScreen(TitleContainerConfigScreen::new))))));
}
/**
diff --git a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainerConfigScreen.java b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainerConfigScreen.java
index e729ea15..c0c4d63c 100644
--- a/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainerConfigScreen.java
+++ b/src/main/java/me/xmrvizzy/skyblocker/utils/title/TitleContainerConfigScreen.java
@@ -21,8 +21,8 @@ public class TitleContainerConfigScreen extends Screen {
private float hudX = SkyblockerConfig.get().general.titleContainer.x;
private float hudY = SkyblockerConfig.get().general.titleContainer.y;
- protected TitleContainerConfigScreen(Text title) {
- super(title);
+ protected TitleContainerConfigScreen() {
+ super(Text.of("Title Container HUD Config"));
}
@Override