diff --git a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java index d58153bc7..ef1ee9ea3 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java +++ b/type.generic/src/main/java/net/swofty/type/generic/event/actions/gui/ActionPlayerInventoryClick.java @@ -87,7 +87,7 @@ public void run(InventoryPreClickEvent event) { false ), HypixelInventoryGUI.CloseReason.SIGN_OPENED); - new HypixelSignGUI(player).open(query.lines()).thenAccept(string -> { + new HypixelSignGUI(player).open(query.lines(), query.arrowLine()).thenAccept(string -> { HypixelInventoryGUI nextGui = query.onQueryFinish(string, player); if (nextGui != null && string != null) nextGui.open(player); diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/HypixelSignGUI.java b/type.generic/src/main/java/net/swofty/type/generic/gui/HypixelSignGUI.java index da076c5be..db6ca93d5 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/HypixelSignGUI.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/HypixelSignGUI.java @@ -27,6 +27,10 @@ public HypixelSignGUI(HypixelPlayer player) { } public CompletableFuture open(String[] text) { + return open(text, "^^^^^^^^"); + } + + public CompletableFuture open(String[] text, String arrowLine) { Pos pos = player.getPosition().add(0, 6, 0); CompoundBinaryTag compound = CompoundBinaryTag.builder() @@ -46,7 +50,7 @@ public CompletableFuture open(String[] text) { .put("color", StringBinaryTag.stringBinaryTag("black")) .put("messages", ListBinaryTag.from(List.of( StringBinaryTag.stringBinaryTag(""), - StringBinaryTag.stringBinaryTag("^^^^^^^^"), + StringBinaryTag.stringBinaryTag(arrowLine), StringBinaryTag.stringBinaryTag(text[0]), StringBinaryTag.stringBinaryTag(text[1]) ))) diff --git a/type.generic/src/main/java/net/swofty/type/generic/gui/inventory/item/GUIQueryItem.java b/type.generic/src/main/java/net/swofty/type/generic/gui/inventory/item/GUIQueryItem.java index 1ea979d07..a71cdc9b9 100644 --- a/type.generic/src/main/java/net/swofty/type/generic/gui/inventory/item/GUIQueryItem.java +++ b/type.generic/src/main/java/net/swofty/type/generic/gui/inventory/item/GUIQueryItem.java @@ -31,4 +31,8 @@ public void run(InventoryPreClickEvent e, HypixelPlayer player) {} public String[] lines() { return new String[]{"Enter your", "input"}; } -} \ No newline at end of file + + public String arrowLine() { + return "^^^^^^^^"; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java index 48ec42f11..d864f33d5 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/SkyBlockGenericLoader.java @@ -80,6 +80,7 @@ import net.swofty.type.skyblockgeneric.user.SkyBlockPlayer; import net.swofty.type.skyblockgeneric.user.SkyBlockScoreboard; import net.swofty.type.skyblockgeneric.user.StashReminder; + import net.swofty.type.generic.user.categories.CustomGroups; import net.swofty.type.skyblockgeneric.user.fairysouls.FairySoul; import net.swofty.type.skyblockgeneric.user.fairysouls.FairySoulZone; @@ -295,7 +296,7 @@ public void initialize(MinecraftServer server) { MinecraftServer.getDimensionTypeRegistry().register( Key.key("skyblock:island"), DimensionType.builder() - .ambientLight(1) + .ambientLight(0f) .build()); SkyBlockIsland.runVacantLoop(MinecraftServer.getSchedulerManager()); @@ -326,6 +327,7 @@ public void initialize(MinecraftServer server) { // Start repeaters SkyBlockScoreboard.start(); StashReminder.start(MinecraftServer.getSchedulerManager()); + PlayerHolograms.updateAll(MinecraftServer.getSchedulerManager()); /** diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/calendar/SkyBlockCalendar.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/calendar/SkyBlockCalendar.java index 2bc1e5e00..94f7230e9 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/calendar/SkyBlockCalendar.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/calendar/SkyBlockCalendar.java @@ -158,7 +158,8 @@ public static String getDisplay(long elapsed) { int currentTime = (int) ((elapsed % DAY) - 6000); if (currentTime < 0) currentTime += DAY; int hours = 6 + (currentTime / 1000); - int minutes = (currentTime % 1000) * 60 / 1000; // Corrected minutes calculation + int minutes = (currentTime % 1000) * 60 / 1000; + minutes = (minutes / 10) * 10; String formattedMinutes = String.format("%02d", minutes); if (hours >= 24) hours -= 24; if (hours < 6 || hours >= 20) isDaytime = false; diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java index 39a5255cc..9e6cc6ef8 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/event/actions/player/mobdamage/PlayerActionDamagedAttacked.java @@ -36,7 +36,9 @@ public void run(EntityAttackEvent event) { (SkyBlockPlayer) event.getTarget(), damageDealt.getKey().floatValue(), mob); SkyBlockValueEvent.callValueUpdateEvent(valueEvent); - ((SkyBlockPlayer) event.getTarget()).damage(new EntityDamage(mob, (float) valueEvent.getValue())); + SkyBlockPlayer damagedPlayer = (SkyBlockPlayer) event.getTarget(); + damagedPlayer.markMobHit(); + damagedPlayer.damage(new EntityDamage(mob, (float) valueEvent.getValue())); new DamageIndicator() .damage((float) valueEvent.getValue()) diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerDeposit.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerDeposit.java index 3fe272b1b..f8124fe1d 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerDeposit.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerDeposit.java @@ -37,10 +37,10 @@ public ItemStack.Builder getItem(HypixelPlayer p) { return ItemStackCreator.getStack("§aYour whole purse", Material.CHEST, 64, "§8Bank deposit", " ", - "§7Current balance: §6" + StringUtility.decimalify( - player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount(), 1 + "§7Current balance: §6" + formatCoinAmount( + player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount() ), - "§7Amount to deposit: §6" + StringUtility.decimalify(player.getCoins(), 1), + "§7Amount to deposit: §6" + formatCoinAmount(player.getCoins()), " ", "§eClick to deposit coins!" ); @@ -61,10 +61,10 @@ public ItemStack.Builder getItem(HypixelPlayer p) { return ItemStackCreator.getStack("§aHalf of your purse", Material.CHEST, 32, "§8Bank deposit", " ", - "§7Current balance: §6" + StringUtility.decimalify( - player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount(), 1 + "§7Current balance: §6" + formatCoinAmount( + player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount() ), - "§7Amount to deposit: §6" + StringUtility.decimalify(player.getCoins() / 2, 1), + "§7Amount to deposit: §6" + formatCoinAmount(player.getCoins() / 2), " ", "§eClick to deposit coins!" ); @@ -107,8 +107,8 @@ public ItemStack.Builder getItem(HypixelPlayer p) { return ItemStackCreator.getStack("§aCustom amount", Material.OAK_SIGN, 1, "§8Bank deposit", " ", - "§7Current balance: §6" + StringUtility.decimalify( - player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount(), 1 + "§7Current balance: §6" + formatCoinAmount( + player.getSkyblockDataHandler().get(net.swofty.type.skyblockgeneric.data.SkyBlockDataHandler.Data.BANK_DATA, DatapointBankData.class).getValue().getAmount() ), "§7Amount to deposit: §6Custom", " ", @@ -151,8 +151,8 @@ private void attemptDeposit(SkyBlockPlayer player, double amount) { player.getUsername() )); - player.sendMessage("§aYou have deposited §6" + StringUtility.decimalify(amount, 1) + " coins§a! You now have §6" + - StringUtility.decimalify(bankData.getAmount(), 1) + player.sendMessage("§aYou have deposited §6" + formatCoinAmount(amount) + " coins§a! You now have §6" + + formatCoinAmount(bankData.getAmount()) + " coins§a in your account."); return; } @@ -178,8 +178,8 @@ private void attemptDeposit(SkyBlockPlayer player, double amount) { latestBankData.addTransaction(new DatapointBankData.Transaction( System.currentTimeMillis(), amount, player.getUsername())); - player.sendMessage("§aYou have deposited §6" + StringUtility.decimalify(amount, 1) + - " coins§a! You now have §6" + StringUtility.decimalify(latestBankData.getAmount(), 1) + + player.sendMessage("§aYou have deposited §6" + formatCoinAmount(amount) + + " coins§a! You now have §6" + formatCoinAmount(latestBankData.getAmount()) + " coins§a in your account."); return latestBankData; // Return modified data to be propagated to all servers @@ -199,4 +199,11 @@ public boolean allowHotkeying() { public void onBottomClick(InventoryPreClickEvent e) { e.setCancelled(true); } + + private String formatCoinAmount(double amount) { + if (amount >= 1000) { + return StringUtility.shortenNumber(amount).replace("K", "k"); + } + return StringUtility.decimalify(amount, 1); + } } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerWithdraw.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerWithdraw.java index d8b8c7f9f..b4767b941 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerWithdraw.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/banker/GUIBankerWithdraw.java @@ -110,7 +110,7 @@ public ItemStack.Builder getItem(HypixelPlayer p) { public HypixelInventoryGUI onQueryFinish(String query, HypixelPlayer p) { SkyBlockPlayer player = (SkyBlockPlayer) p; try { - double amount = Double.parseDouble(query); + double amount = parseAmountInput(query); if (amount > bankBalance) { player.sendMessage("§cYou do not have that many coins to withdraw!"); return null; @@ -128,6 +128,16 @@ public HypixelInventoryGUI onQueryFinish(String query, HypixelPlayer p) { return null; } + @Override + public String[] lines() { + return new String[]{"Enter the amount", "to withdraw"}; + } + + @Override + public String arrowLine() { + return "^^^^^^^^^^^^^^^^^"; + } + @Override public ItemStack.Builder getItem(HypixelPlayer p) { SkyBlockPlayer player = (SkyBlockPlayer) p; @@ -226,4 +236,25 @@ public boolean allowHotkeying() { public void onBottomClick(InventoryPreClickEvent e) { e.setCancelled(true); } -} \ No newline at end of file + + private double parseAmountInput(String input) { + if (input == null) throw new NumberFormatException("null input"); + String cleaned = input.trim().toLowerCase(); + if (cleaned.isEmpty()) throw new NumberFormatException("empty input"); + + double multiplier = 1D; + char suffix = cleaned.charAt(cleaned.length() - 1); + if (suffix == 'k' || suffix == 'm' || suffix == 'b') { + cleaned = cleaned.substring(0, cleaned.length() - 1).trim(); + multiplier = switch (suffix) { + case 'k' -> 1_000D; + case 'm' -> 1_000_000D; + case 'b' -> 1_000_000_000D; + default -> 1D; + }; + } + + double base = Double.parseDouble(cleaned); + return base * multiplier; + } +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/sbmenu/GUICrafting.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/sbmenu/GUICrafting.java index 056f9f4a9..a3cd284df 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/sbmenu/GUICrafting.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/gui/inventories/sbmenu/GUICrafting.java @@ -23,6 +23,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -57,7 +58,16 @@ public void layout(ViewLayout layout, CraftingState state, ViewCo Material borderMaterial = canCraft ? Material.LIME_STAINED_GLASS_PANE : Material.RED_STAINED_GLASS_PANE; Components.fill(layout); layout.slots(Layouts.row(5), (s, c) -> ItemStackCreator.createNamedItemStack(borderMaterial)); - Components.close(layout, 49); + layout.slot(49, (s, c) -> ItemStack.builder(Material.ARROW) + .set(DataComponents.CUSTOM_NAME, Component.text("§aGo Back")) + .set(DataComponents.LORE, List.of(Component.text("§7To SkyBlock Menu") + .decoration(TextDecoration.ITALIC, false))), + (click, c) -> { + ViewNavigator navigator = ViewNavigator.get(c.player()); + if (!navigator.pop()) { + c.player().closeInventory(); + } + }); Components.containerGrid( layout, @@ -228,4 +238,3 @@ public boolean onBottomClick(ClickContext click, ViewContext ctx) public record CraftingState(int lastGridHash, SkyBlockRecipe lastParsedRecipe) { } } - diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java index b952fbf5b..516254f05 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockIsland.java @@ -42,6 +42,9 @@ public class SkyBlockIsland { private static final String ISLAND_TEMPLATE_NAME = CustomWorlds.SKYBLOCK_ISLAND_TEMPLATE.getFolderName(); private static final Map loadedIslands = new HashMap<>(); + private static final long ISLAND_INITIAL_TIME = 1000L; + private static final int ISLAND_TIME_RATE = 1; + private static final int ISLAND_TIME_SYNC_TICKS = 20; // Internal Island Data private final IslandDatabase database; @@ -83,6 +86,9 @@ public CompletableFuture getSharedInstance() { ); InstanceContainer temporaryInstance = manager.createInstanceContainer(dimensionTypeKey); islandInstance = manager.createSharedInstance(temporaryInstance); + islandInstance.setTime(ISLAND_INITIAL_TIME); + islandInstance.setTimeRate(ISLAND_TIME_RATE); + islandInstance.setTimeSynchronizationTicks(ISLAND_TIME_SYNC_TICKS); List onlinePlayers; if (coop != null) { @@ -197,4 +203,4 @@ public static void runVacantLoop(Scheduler scheduler) { return TaskSchedule.tick(4); }, ExecutionType.TICK_END); } -} \ No newline at end of file +} diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java index 17aca8a03..076eb68d4 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockPlayer.java @@ -71,6 +71,7 @@ @Getter public class SkyBlockPlayer extends HypixelPlayer { + private static final long VOID_MOB_HIT_WINDOW_MS = 8000; private final PlayerAbilityHandler abilityHandler = new PlayerAbilityHandler(); @Getter private final PlayerStatistics statistics = new PlayerStatistics(this); @@ -89,6 +90,7 @@ public class SkyBlockPlayer extends HypixelPlayer { public boolean speedManaged = false; @Setter private SkyBlockIsland skyBlockIsland; + private long lastMobHitAt = 0L; private static final Pattern SACK_PATTERN = Pattern.compile("^(?:(SMALL|MEDIUM|LARGE|ENCHANTED)_)?(.+?)_SACK$"); @@ -932,6 +934,14 @@ public DatapointDeaths.PlayerDeaths getDeathData() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.DEATHS, DatapointDeaths.class).getValue(); } + public void markMobHit() { + this.lastMobHitAt = System.currentTimeMillis(); + } + + public boolean wasRecentlyHitByMobForVoidDeath() { + return System.currentTimeMillis() - this.lastMobHitAt <= VOID_MOB_HIT_WINDOW_MS; + } + public DatapointCollectedMobTypeRewards.PlayerCollectedMobTypeRewards getCollectedMobTypesData() { return getSkyblockDataHandler().get(SkyBlockDataHandler.Data.COLLECTED_MOB_TYPE_REWARDS, DatapointCollectedMobTypeRewards.class).getValue(); } diff --git a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockScoreboard.java b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockScoreboard.java index eb83cf088..5c4859874 100644 --- a/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockScoreboard.java +++ b/type.skyblockgeneric/src/main/java/net/swofty/type/skyblockgeneric/user/SkyBlockScoreboard.java @@ -74,7 +74,10 @@ public static void start() { } lines.add("§7 "); lines.add("§fPurse: §6" + StringUtility.commaify(dataHandler.get(SkyBlockDataHandler.Data.COINS, DatapointDouble.class).getValue())); - lines.add("§fBits: §b" + StringUtility.commaify(dataHandler.get(SkyBlockDataHandler.Data.BITS, DatapointInteger.class).getValue())); + int bits = dataHandler.get(SkyBlockDataHandler.Data.BITS, DatapointInteger.class).getValue(); + if (bits >= 1) { + lines.add("§fBits: §b" + StringUtility.commaify(bits)); + } // Dark Auction section if (DarkAuctionHandler.isPlayerInAuction(player.getUuid())