Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/main/java/dev/pozzoo/quickwaystones/QuickWaystones.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import dev.pozzoo.quickwaystones.items.WaystonePass;
import dev.pozzoo.quickwaystones.managers.CraftManager;
import dev.pozzoo.quickwaystones.managers.DataManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.Set;
Expand All @@ -24,6 +26,7 @@ public final class QuickWaystones extends JavaPlugin {
private static final Map<Location, WaystoneData> waystonesMap =
new HashMap<>();
private static final Map<UUID, Set<Integer>> playerAccess = new HashMap<>();
private static final Map<UUID, List<Integer>> playerWaystoneOrder = new HashMap<>();
private static int lastWaystoneID = 0;
private static WaystonePass waystonePass;
private static Metrics metrics;
Expand Down Expand Up @@ -121,12 +124,16 @@ public static Set<Integer> getOrCreatePlayerAccess(UUID uuid) {
return playerAccess.computeIfAbsent(uuid, ignored -> new HashSet<>());
}

public static Map<UUID, List<Integer>> getPlayerWaystoneOrder() {
return playerWaystoneOrder;
}

public static WaystonePass getWaystonePass() {
return waystonePass;
}

public static void saveData() {
dataManager.saveData(waystonesMap.values(), playerAccess);
dataManager.saveData(waystonesMap.values(), playerAccess, playerWaystoneOrder);
}

public static boolean existsInMap(Location location) {
Expand Down
104 changes: 104 additions & 0 deletions src/main/java/dev/pozzoo/quickwaystones/gui/WaystoneGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.plugin.Plugin;

import java.util.*;
import java.util.stream.Collectors;

public class WaystoneGUI implements Listener {

Expand All @@ -25,8 +29,12 @@ public class WaystoneGUI implements Listener {
private static final int PREV_SLOT = 27 + (3 - 1); // 29
private static final int NEXT_SLOT = 27 + (7 - 1); // 33
private static final int PAGE_SLOT = 27 + (5 - 1); // 31
private static final int REORDER_SLOT = 27 + (9 - 1); // 35

private static volatile boolean registered = false;
private static final Set<UUID> reorderingPlayers = new HashSet<>();
private static final Map<UUID, Integer> firstSelections = new HashMap<>();
private static final Set<UUID> reopeningPlayers = new HashSet<>();

public static void runGUI(Player player, WaystoneData waystoneData) {
ensureRegistered();
Expand Down Expand Up @@ -56,6 +64,17 @@ private static void openPage(Player player, int page, WaystoneData waystoneData)

List<WaystoneData> waystones = new ArrayList<>(waystonesMap.values());

List<Integer> playerOrder = QuickWaystones.getPlayerWaystoneOrder().get(player.getUniqueId());
if (playerOrder != null && !playerOrder.isEmpty()) {
Map<Integer, Integer> orderIndex = new HashMap<>();
for (int i = 0; i < playerOrder.size(); i++) {
orderIndex.put(playerOrder.get(i), i);
}
waystones.sort(Comparator.comparingInt(ws -> orderIndex.getOrDefault(ws.getId(), Integer.MAX_VALUE)));
} else {
waystones.sort(Comparator.comparingInt(WaystoneData::getId));
}

int totalItems = waystones.size();
int totalPages = Math.max(1, (int) Math.ceil(totalItems / (double) PAGE_SIZE));
int currentPage = Math.max(0, Math.min(page, totalPages - 1));
Expand All @@ -68,13 +87,17 @@ private static void openPage(Player player, int page, WaystoneData waystoneData)
// Fill page items (top 27 slots)
int startIndex = currentPage * PAGE_SIZE;
int endIndex = Math.min(startIndex + PAGE_SIZE, totalItems);
Integer selectedId = firstSelections.get(player.getUniqueId());
int slot = 0;
for (int i = startIndex; i < endIndex; i++) {
WaystoneData ws = waystones.get(i);
ItemStack item = new ItemStack(Material.ENDER_PEARL);
ItemMeta meta = item.getItemMeta();
if (meta != null) {
meta.displayName(StringUtils.formatItemName(ws.getName()));
if (selectedId != null && selectedId.intValue() == ws.getId()) {
applyGlint(meta);
}
item.setItemMeta(meta);
}
inv.setItem(slot, item);
Expand All @@ -97,9 +120,37 @@ private static void openPage(Player player, int page, WaystoneData waystoneData)
}
}

// Reorder button
boolean reordering = reorderingPlayers.contains(player.getUniqueId());
ItemStack reorderBtn = new ItemStack(Material.CRAFTING_TABLE);
ItemMeta btnMeta = reorderBtn.getItemMeta();
if (btnMeta != null) {
if (reordering) {
btnMeta.displayName(StringUtils.formatString("<green>Reordering"));
applyGlint(btnMeta);
} else {
btnMeta.displayName(StringUtils.formatString("Reorder"));
}
reorderBtn.setItemMeta(btnMeta);
}
inv.setItem(REORDER_SLOT, reorderBtn);

reopeningPlayers.add(player.getUniqueId());
player.openInventory(inv);
}

private static void applyGlint(ItemMeta meta) {
try {
meta.setEnchantmentGlintOverride(true);
} catch (NoSuchMethodError ignored) {
Enchantment unbreaking = Registry.ENCHANTMENT.get(NamespacedKey.minecraft("unbreaking"));
if (unbreaking != null) {
meta.addEnchant(unbreaking, 1, true);
}
meta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
}
}

private static ItemStack named(Component name) {
ItemStack item = new ItemStack(Material.PAPER);
ItemMeta meta = item.getItemMeta();
Expand Down Expand Up @@ -155,9 +206,49 @@ public void onInventoryClick(InventoryClickEvent event) {
return;
}

// Reorder button
if (slot == REORDER_SLOT) {
UUID playerId = player.getUniqueId();
if (reorderingPlayers.contains(playerId)) {
reorderingPlayers.remove(playerId);
firstSelections.remove(playerId);
} else {
reorderingPlayers.add(playerId);
}
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 0.5f, 1.5f);
openPage(player, holder.page, holder.waystoneData);
return;
}

// Waystone teleport
WaystoneData ws = holder.slotToWaystone.get(slot);
if (ws != null) {
UUID playerId = player.getUniqueId();
if (reorderingPlayers.contains(playerId)) {
Integer selected = firstSelections.get(playerId);
if (selected == null) {
firstSelections.put(playerId, ws.getId());
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 0.5f, 1.0f);
} else if (selected.intValue() == ws.getId()) {
firstSelections.remove(playerId);
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 0.5f, 1.0f);
} else {
List<Integer> order = QuickWaystones.getPlayerWaystoneOrder()
.computeIfAbsent(playerId, ignored -> QuickWaystones.getPlayerAccess()
.getOrDefault(playerId, new HashSet<>())
.stream().sorted()
.collect(Collectors.toCollection(ArrayList::new)));
if (!order.contains(selected)) order.add(selected);
if (!order.contains(ws.getId())) order.add(ws.getId());
Collections.swap(order, order.indexOf(selected), order.indexOf(ws.getId()));
QuickWaystones.saveData();
firstSelections.remove(playerId);
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 0.5f, 1.5f);
}
openPage(player, holder.page, holder.waystoneData);
return;
}

if (ws.getId() == holder.waystoneData.getId()) {
String message = QuickWaystones.getInstance().getConfig().getString("Messages.SameWaystone", "You cannot teleport to the same waystone!");
player.sendMessage(StringUtils.formatString("<red>" + message));
Expand Down Expand Up @@ -188,4 +279,17 @@ public void onInventoryClick(InventoryClickEvent event) {
player.closeInventory();
}
}

@EventHandler
public void onInventoryClose(InventoryCloseEvent event) {
if (!(event.getInventory().getHolder() instanceof WaystoneHolder)) {
return;
}
UUID playerId = event.getPlayer().getUniqueId();
if (reopeningPlayers.remove(playerId)) {
return;
}
reorderingPlayers.remove(playerId);
firstSelections.remove(playerId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import java.util.logging.Logger;
import org.bukkit.Location;
import org.bukkit.configuration.ConfigurationSection;
Expand Down Expand Up @@ -119,12 +120,22 @@ public int loadData() {
}
}

ConfigurationSection orderSection = config.getConfigurationSection("Order");
if (orderSection != null) {
for (String key : orderSection.getKeys(false)) {
UUID playerId = UUID.fromString(key);
List<Integer> order = new ArrayList<>(config.getIntegerList("Order." + key));
QuickWaystones.getPlayerWaystoneOrder().put(playerId, order);
}
}

return lastComputedId;
}

public void saveData(
Iterable<WaystoneData> waystones,
Map<UUID, Set<Integer>> playerAccess
Map<UUID, Set<Integer>> playerAccess,
Map<UUID, List<Integer>> playerWaystoneOrder
) {
config = new YamlConfiguration();
config.set(
Expand Down Expand Up @@ -161,6 +172,19 @@ public void saveData(
)
);

playerWaystoneOrder
.entrySet()
.stream()
.sorted(
Map.Entry.comparingByKey(Comparator.comparing(UUID::toString))
)
.forEach(entry ->
config.set(
"Order." + entry.getKey(),
entry.getValue().stream().collect(Collectors.toList())
)
);

save();
}

Expand Down