diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java b/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java index e2375a85..60c3a387 100644 --- a/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java +++ b/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java @@ -100,6 +100,16 @@ public void addPage(Vec pos, Direction face) { this.pageFaces.add(new PageResource(pos, face)); } + /** + * Removes a page from the map. + * + * @param pageResource the page resource to remove + * @return true if the page was removed + */ + public boolean removePage(PageResource pageResource) { + return this.pageFaces.remove(pageResource); + } + /** * Returns the {@link Set} of {@link PageResource} which are used for the game. * diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java index c2fb3cd5..319609ae 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java @@ -5,28 +5,43 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; +import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Player; import net.minestom.server.instance.anvil.AnvilLoader; +import net.minestom.server.utils.Direction; import net.minestom.server.world.DimensionType; +import net.minestom.server.inventory.InventoryType; import net.onelitefeather.cygnus.common.map.GameMap; import net.onelitefeather.cygnus.common.map.GameMapBuilder; import net.onelitefeather.cygnus.common.util.GsonHelper; +import net.onelitefeather.cygnus.setup.inventory.page.PageHeaderFormatter; +import net.onelitefeather.cygnus.setup.inventory.slot.PageSlot; import net.onelitefeather.cygnus.setup.inventory.view.InventoryMode; import net.onelitefeather.cygnus.setup.inventory.view.MapDataOverviewInventory; import net.onelitefeather.cygnus.setup.inventory.view.SurvivorViewInventory; import net.onelitefeather.cygnus.setup.item.SetupItemId; import net.onelitefeather.cygnus.setup.item.SetupItems; import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import net.onelitefeather.cygnus.common.page.PageResource; +import net.onelitefeather.cygnus.setup.player.SetupPlayer; import net.onelitefeather.cygnus.setup.util.SetupMessages; +import net.theevilreaper.aves.inventory.layout.InventoryLayout; +import net.theevilreaper.aves.inventory.pageable.PageableInventory; +import net.theevilreaper.aves.inventory.pageable.TitleData; +import net.theevilreaper.aves.inventory.slot.ISlot; +import net.theevilreaper.aves.inventory.util.LayoutCalculator; import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; public class GameData extends InstanceSetupData { private final MapDataOverviewInventory inventory; private final SurvivorViewInventory survivorInventory; + private final PageableInventory pageInventory; private GameMapBuilder gameMapBuilder; private boolean pageMode; private boolean survivorMode; @@ -43,6 +58,59 @@ public GameData(Player player, MapEntry mapEntry) { this.inventory = new MapDataOverviewInventory(player, this.gameMapBuilder, InventoryMode.GAME); this.survivorInventory = new SurvivorViewInventory(player, this.gameMapBuilder); + this.pageInventory = createPageInventory(player); + } + + /** + * Creates the [{@link PageableInventory} to display the given {@link PageResource}s. + * + * @param player who owns the inventory + * @return the created inventory + */ + private PageableInventory createPageInventory(Player player) { + InventoryLayout layout = InventoryLayout.fromType(InventoryType.CHEST_6_ROW); + layout.setItems(LayoutCalculator.fillRow(InventoryType.CHEST_1_ROW), SetupItems.DECORATION_PANE); + layout.setItems(LayoutCalculator.fillRow(InventoryType.CHEST_6_ROW), SetupItems.DECORATION_PANE); + + return PageableInventory + .builder() + .titleData( + TitleData + .builder() + .title(Component.text("Page positions - ")) + .pageMapper(PageHeaderFormatter::format) + .showPageNumbers(true) + .build() + ) + .player(player) + .slotRange(LayoutCalculator.quad(InventoryType.CHEST_1_ROW.getSize(), InventoryType.CHEST_5_ROW.getSize() - 1)) + .layout(layout) + .values(getPageSlots()) + .build(); + } + + /** + * Adds a new {@link PageResource} to the builder and inventory + * + * @param pos of the resource + * @param face of the resource + */ + public void addPage(Vec pos, Direction face) { + PageResource pageResource = new PageResource(pos, face); + this.gameMapBuilder.addPage(pos, face); + this.pageInventory.add(new PageSlot(pageResource)); + } + + /** + * Returns the list of slots for the given {@link PageResource}s + * + * @return the created list + */ + private List getPageSlots() { + if (this.gameMapBuilder.getPageFaces().isEmpty()) return new ArrayList<>(); + List pageSlots = new ArrayList<>(this.gameMapBuilder.getPageFaces().size()); + this.gameMapBuilder.getPageFaces().forEach(pageFace -> pageSlots.add(new PageSlot(pageFace))); + return pageSlots; } /** @@ -52,6 +120,9 @@ public void swapPageMode() { this.pageMode = !this.pageMode; } + /** + * Swaps to the survivor mode. + */ public void swapSurvivorMode() { this.survivorMode = !this.survivorMode; } @@ -64,9 +135,7 @@ public void openInventory(InventoryTarget target) { switch (target) { case GENERAL -> this.inventory.open(); case SURVIVOR -> this.survivorInventory.open(); - case PAGE -> { - - } + case PAGE -> this.pageInventory.open(); } } @@ -79,7 +148,6 @@ public void triggerUpdate(InventoryTarget target) { case GENERAL -> this.inventory.invalidateDataLayout(); case SURVIVOR -> this.survivorInventory.invalidateDataLayout(); case PAGE -> { - // Nothing to do here } } } @@ -89,7 +157,6 @@ public void triggerUpdate(InventoryTarget target) { */ @Override public void updateTitle() { - System.out.println("TItle is " + (title == null)); if (getMapBuilder().getName().equalsIgnoreCase("Map")) { this.title = null; super.updateTitle(); @@ -168,6 +235,11 @@ public void handleItemInteraction(Player player, byte tagValue) { return; } + if (SetupItemId.PAGES == tagValue) { + this.openInventory(InventoryTarget.PAGE); + return; + } + super.handleItemInteraction(player, tagValue); } @@ -194,9 +266,19 @@ public void handleDataDelete(MapDataCategory category) { */ @Override public void handleDataContextDelete(MapDataCategory category, Point point) { - if (point instanceof Pos pos) { + if (category == MapDataCategory.SURVIVOR && point instanceof Pos pos) { this.gameMapBuilder.removeSurvivorSpawn(pos); this.triggerUpdate(InventoryTarget.SURVIVOR); + } else if (category == MapDataCategory.PAGE) { + Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(this.uuid); + PageResource pageResource = null; + if (player instanceof SetupPlayer setupPlayer) { + pageResource = setupPlayer.getPageResource(); + } + if (pageResource != null) { + this.gameMapBuilder.removePage(pageResource); + this.pageInventory.remove(new PageSlot(pageResource)); + } } } @@ -228,6 +310,7 @@ public void reset() { super.reset(); this.survivorInventory.unregister(); this.inventory.unregister(); + this.pageInventory.unregister(); } /** @@ -262,6 +345,11 @@ public boolean hasPageMode() { return pageMode; } + /** + * Returns an indication if the survivor mode is active or not. + * + * @return true for yes otherwise false + */ public boolean hasSurvivorMode() { return this.survivorMode; } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/MapDialogs.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/MapDialogs.java index c10eae35..8a385848 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/MapDialogs.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/MapDialogs.java @@ -7,6 +7,8 @@ import net.minestom.server.dialog.DialogAction; import net.minestom.server.dialog.DialogAfterAction; import net.minestom.server.entity.Player; +import net.minestom.server.coordinate.Point; +import net.onelitefeather.cygnus.common.page.PageResource; import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.onelitefeather.cygnus.setup.util.DialogBase; @@ -27,7 +29,6 @@ public final class MapDialogs extends DialogBase { public static final Key NON_DYNAMIC_DELETE_KEY = create("non_dynamic_delete_dialog"); public static final Key DYNAMIC_DELETE_KEY = create("dynamic_delete_dialog"); - /** * Opens the dialog to allow the input of a name. * @@ -97,7 +98,11 @@ public static void openDeleteDialog(Player player, MapDataCategory mapDataCatego } public static void openDeleteDialog(Player player, MapDataCategory mapDataCategory, @Nullable DialogContext context) { - DialogContext.PositionContent positionContent = (DialogContext.PositionContent) context; + Point point = switch (context) { + case DialogContext.PositionContent(Point p) -> p; + case DialogContext.PageContent(PageResource resource) -> resource.position(); + default -> null; + }; DialogTemplate dialogTemplate = DialogType.confirm(DYNAMIC_DELETE_KEY) .meta(dialogMeta -> { dialogMeta.closeWithEscape(false); @@ -109,16 +114,18 @@ public static void openDeleteDialog(Player player, MapDataCategory mapDataCatego template.contents(Component.text("Do you want to delete the following data?"))); dialogMeta.emptyMessage(); dialogMeta.messageBody(template -> template.contents(Component.text("Category: ").append(Component.text(mapDataCategory.getName())))); - dialogMeta.emptyMessage(); - dialogMeta.messageBody(componentTemplate -> { - componentTemplate.contents(Component.text("x: ", NamedTextColor.WHITE).append(Component.text(positionContent.point().x()))); - }); - dialogMeta.messageBody(componentTemplate -> { - componentTemplate.contents(Component.text("y: ", NamedTextColor.WHITE).append(Component.text(positionContent.point().y()))); - }); - dialogMeta.messageBody(componentTemplate -> { - componentTemplate.contents(Component.text("z: ", NamedTextColor.WHITE).append(Component.text(positionContent.point().z()))); - }); + if (point != null) { + dialogMeta.emptyMessage(); + dialogMeta.messageBody(componentTemplate -> { + componentTemplate.contents(Component.text("x: ", NamedTextColor.WHITE).append(Component.text(point.x()))); + }); + dialogMeta.messageBody(componentTemplate -> { + componentTemplate.contents(Component.text("y: ", NamedTextColor.WHITE).append(Component.text(point.y()))); + }); + dialogMeta.messageBody(componentTemplate -> { + componentTemplate.contents(Component.text("z: ", NamedTextColor.WHITE).append(Component.text(point.z()))); + }); + } }) .yesButton(button -> button.width(101).label(Component.text("Save")) .action(new DialogAction.DynamicCustom(DYNAMIC_DELETE_KEY, getCategoryPayload(mapDataCategory.ordinal()))) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java index 3bfedbe4..6d7bd57a 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java @@ -34,7 +34,7 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { point = player.getSurvivorToDelete(); } if (category == MapDataCategory.PAGE) { - point = player.getPageToDelete(); + point = player.getPageToDelete() != null ? player.getPageToDelete() : (player.getPageResource() != null ? player.getPageResource().position() : null); } ((InstanceSetupData)data).handleDataContextDelete(category, point); if (category == MapDataCategory.SURVIVOR) { @@ -42,6 +42,7 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { } if (category == MapDataCategory.PAGE) { player.setPageToDelete(null); + player.setPageResource(null); } }); diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogContext.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogContext.java index c24979ef..ef9e3b0c 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogContext.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogContext.java @@ -1,20 +1,22 @@ package net.onelitefeather.cygnus.setup.event.dialog; import net.minestom.server.coordinate.Point; +import net.onelitefeather.cygnus.common.page.PageResource; /** * Represents the context for a dialog event which contains all necessary data * to open the correct dialog for a specific {@link DialogTarget}. * * @author Joltra - * @version 1.0.0 + * @version 1.5.0 * @see DialogTarget * @since 0.1.0 */ public sealed interface DialogContext permits DialogContext.NameContext, DialogContext.PositionContent, - DialogContext.AuthorAmount { + DialogContext.AuthorAmount, + DialogContext.PageContent { /** * Specific context for the update or deletion of a name. @@ -34,5 +36,21 @@ record PositionContent(Point point) implements DialogContext { } - record AuthorAmount(float amount) implements DialogContext {} + /** + * Specific context to indicate how many authors a map should have. + * + * @param amount of author + */ + record AuthorAmount(float amount) implements DialogContext { + + } + + /** + * Context implementation to bind a {@link PageResource} to a dialog. + * + * @param resource to bind + */ + record PageContent(PageResource resource) implements DialogContext { + + } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatter.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatter.java new file mode 100644 index 00000000..5b36f45f --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatter.java @@ -0,0 +1,29 @@ +package net.onelitefeather.cygnus.setup.inventory.page; + +import net.kyori.adventure.text.Component; +import org.jetbrains.annotations.Contract; + +/** + * Small helper class to format the current number of pages and the total ones to a {@link Component}. + * + * @author theEvilReaper + * @since 2.6.0 + * @version 1.0.0 + */ +public final class PageHeaderFormatter { + + /** + * Returns a {@link Component} that contains the current page and the total numbers of pages. + * @param current page count + * @param max page count + * @return the created component + */ + @Contract(value = "_, _ -> new", pure = true) + public static Component format(int current, int max) { + return Component.text("Page " + current + " of " + max); + } + + private PageHeaderFormatter() { + // Nothing to do here + } +} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PageSlot.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PageSlot.java new file mode 100644 index 00000000..6835a6ec --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PageSlot.java @@ -0,0 +1,79 @@ +package net.onelitefeather.cygnus.setup.inventory.slot; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.minestom.server.entity.Player; +import net.minestom.server.event.EventDispatcher; +import net.minestom.server.inventory.click.Click; +import net.minestom.server.item.ItemStack; +import net.onelitefeather.cygnus.common.page.PageResource; +import net.onelitefeather.cygnus.setup.event.PlayerRemoveDataEvent; +import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import net.theevilreaper.aves.inventory.click.ClickHolder; +import net.theevilreaper.aves.util.Components; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; + +import static net.onelitefeather.cygnus.setup.util.PositionFormat.DECIMAL_FORMAT; +import static net.onelitefeather.cygnus.setup.util.SetupMessages.DELETE_CLICK; +import static net.onelitefeather.cygnus.setup.util.SetupMessages.TELEPORT_CLICK; + +public class PageSlot extends AbstractDataSlot { + + private final PageResource pageResource; + + public PageSlot(PageResource pageResource) { + super(MapDataCategory.PAGE); + this.pageResource = pageResource; + } + + @Override + public ItemStack getItem() { + ItemStack.Builder overviewItem = ItemStack.builder(type.getMaterial()) + .customName(Component.text("Page", type.getColor())); + List lore = new ArrayList<>(); + lore.add(Component.empty()); + lore.add(Component.text("Face: ").append(Component.text(pageResource.face().name(), type.getColor()))); + lore.addAll(Components.pointToLore(MiniMessage.miniMessage(), pageResource.position(), DECIMAL_FORMAT)); + lore.add(Component.empty()); + lore.add(TELEPORT_CLICK); + lore.add(DELETE_CLICK); + lore.add(Component.empty()); + + return overviewItem.lore(lore).build(); + } + + @Override + protected void click(Player player, int slot, Click click, ItemStack stack, Consumer result) { + result.accept(ClickHolder.cancelClick()); + + switch (click) { + case Click.Left _ -> { + player.closeInventory(); + //TODO: Teleport one block in front + player.teleport(this.pageResource.position().asPos()); + } + case Click.Right _ -> + EventDispatcher.call(new PlayerRemoveDataEvent(player, type, new DialogContext.PageContent(this.pageResource))); + default -> { + } + } + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PageSlot pageSlot = (PageSlot) o; + return Objects.equals(pageResource, pageSlot.pageResource); + } + + @Override + public int hashCode() { + return Objects.hash(pageResource); + } +} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PositionSlot.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PositionSlot.java index 7bf07eac..888929ad 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PositionSlot.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/PositionSlot.java @@ -15,27 +15,16 @@ import net.theevilreaper.aves.util.Components; import org.jetbrains.annotations.Nullable; -import java.math.RoundingMode; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.util.ArrayList; import java.util.List; -import java.util.Locale; import java.util.function.Consumer; +import static net.onelitefeather.cygnus.setup.util.PositionFormat.DECIMAL_FORMAT; import static net.onelitefeather.cygnus.setup.util.SetupMessages.DELETE_CLICK; import static net.onelitefeather.cygnus.setup.util.SetupMessages.TELEPORT_CLICK; public class PositionSlot extends AbstractDataSlot { - private static final DecimalFormat DECIMAL_FORMAT; - - static { - DECIMAL_FORMAT = new DecimalFormat("#.##"); - DECIMAL_FORMAT.setRoundingMode(RoundingMode.CEILING); - DECIMAL_FORMAT.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)); - } - private final @Nullable Pos position; public PositionSlot(MapDataCategory category, @Nullable Pos position) { diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItemId.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItemId.java index 8ff8a0b9..16737e4b 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItemId.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItemId.java @@ -13,10 +13,11 @@ public final class SetupItemId { public static final byte SAVE_DATA = (byte) 0x01; public static final byte DATA = (byte) 0x02; public static final byte PAGE = (byte) 0x03; - public static final byte LEAVE_PAGE = (byte) 0x04; - public static final byte SURVIVOR = (byte) 0x05; - public static final byte SPAWNS = (byte) 0x06; - public static final byte LEAVE_MODE = (byte) 0x07; + public static final byte PAGES = (byte) 0x04; + public static final byte LEAVE_PAGE = (byte) 0x05; + public static final byte SURVIVOR = (byte) 0x06; + public static final byte SPAWNS = (byte) 0x07; + public static final byte LEAVE_MODE = (byte) 0x08; private SetupItemId() { // Nothing to do here diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java index 625d98d2..a24fc438 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java @@ -96,6 +96,17 @@ public final class SetupItems { gameSetupLayout.set(7, saveItem); pageLayout = new HotBarLayout(); + pageLayout.set(2, ItemStack.builder(Material.COMPASS) + .customName(Component.text("Pages", NamedTextColor.YELLOW)) + .lore( + getLore(SPACE_SEPARATOR + .append(Component.text("View all available ", NamedTextColor.WHITE)) + .append(Component.text("Pages", NamedTextColor.YELLOW)) + ) + ) + .set(Tags.ITEM_TAG, SetupItemId.PAGES) + .build() + ); pageLayout.set(4, ItemStack.builder(Material.BARRIER) .customName(Component.text("Leave mode", NamedTextColor.RED)) .lore( @@ -111,12 +122,12 @@ public final class SetupItems { survivorSpawnLayout = new HotBarLayout(); survivorSpawnLayout.set(2, ItemStack.builder(Material.CHEST) - .customName(Component.text("Spawns", NamedTextColor.AQUA)) - .lore( - getLore(SPACE_SEPARATOR - .append(Component.text("View all available ", NamedTextColor.WHITE)) - .append(Component.text("Survivor ", NamedTextColor.GREEN)) - .append(Component.text("spawns", NamedTextColor.WHITE))) + .customName(Component.text("Spawns", NamedTextColor.AQUA)) + .lore( + getLore(SPACE_SEPARATOR + .append(Component.text("View all available ", NamedTextColor.WHITE)) + .append(Component.text("Survivor ", NamedTextColor.GREEN)) + .append(Component.text("spawns", NamedTextColor.WHITE))) ) .set(Tags.ITEM_TAG, SetupItemId.SPAWNS) .build() diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/PageCreationListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/PageCreationListener.java index 276e15df..479bbf03 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/PageCreationListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/PageCreationListener.java @@ -55,7 +55,7 @@ public void accept(PlayerBlockBreakEvent event) { } Vec position = event.getBlockPosition().asVec(); - ((GameMapBuilder) gameData.getMapBuilder()).addPage(position, direction); + gameData.addPage(position, direction); Component component = Component.text("Created page at: ", NamedTextColor.GRAY) .append(Components.convertPoint(position).style(Style.style(NamedTextColor.GOLD))) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/data/PlayerRemoveDataListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/data/PlayerRemoveDataListener.java index ce9011ad..8c6ae4b6 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/data/PlayerRemoveDataListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/data/PlayerRemoveDataListener.java @@ -1,44 +1,42 @@ package net.onelitefeather.cygnus.setup.listener.data; +import net.minestom.server.coordinate.Point; import net.minestom.server.entity.Player; +import net.onelitefeather.cygnus.common.page.PageResource; import net.onelitefeather.cygnus.setup.dialog.MapDialogs; import net.onelitefeather.cygnus.setup.event.PlayerRemoveDataEvent; import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.onelitefeather.cygnus.setup.player.SetupPlayer; +import java.util.EnumSet; +import java.util.Set; import java.util.function.Consumer; public final class PlayerRemoveDataListener implements Consumer { + + private static final Set CONTEXT_AWARE_CATEGORIES = + EnumSet.of(MapDataCategory.SURVIVOR, MapDataCategory.PAGE); + @Override public void accept(PlayerRemoveDataEvent event) { final Player player = event.getPlayer(); final MapDataCategory category = event.getMapDataCategory(); + final DialogContext context = event.getContext(); - if (event.getContext() == null || (!(category == MapDataCategory.SURVIVOR || category == MapDataCategory.PAGE))) { + if (context == null || !CONTEXT_AWARE_CATEGORIES.contains(category)) { MapDialogs.openDeleteDialog(player, category); return; } + final SetupPlayer setupPlayer = (SetupPlayer) player; - DialogContext context = event.getContext(); - - if (!(context instanceof DialogContext.PositionContent positionContent)) { - player.sendMessage(""); - return; - } - - SetupPlayer setupPlayer = (SetupPlayer) player; - - - switch (category) { - case SURVIVOR -> setupPlayer.setSurvivorToDelete(positionContent.point()); - case PAGE -> setupPlayer.setPageToDelete(positionContent.point()); - default -> { - - } + switch (context) { + case DialogContext.PositionContent(Point point) -> setupPlayer.setSurvivorToDelete(point); + case DialogContext.PageContent(PageResource resource) -> setupPlayer.setPageResource(resource); + default -> { } } MapDialogs.openDeleteDialog(player, category, context); } -} +} \ No newline at end of file diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/player/SetupPlayer.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/player/SetupPlayer.java index 313d9459..1e9697f2 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/player/SetupPlayer.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/player/SetupPlayer.java @@ -4,6 +4,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.network.player.GameProfile; import net.minestom.server.network.player.PlayerConnection; +import net.onelitefeather.cygnus.common.page.PageResource; import net.onelitefeather.cygnus.common.player.InstanceSwitchChunkPlayer; import org.jetbrains.annotations.Nullable; @@ -11,13 +12,14 @@ * Custom {@link Player} implementation to add additional context related to the setup flow. * * @author theEvilReaper - * @version 1.0.0 + * @version 1.2.0 * @since 2.0.0 */ public final class SetupPlayer extends InstanceSwitchChunkPlayer { private @Nullable Point survivorToDelete; private @Nullable Point pageToDelete; + private @Nullable PageResource pageResource; /** * {@inheritDoc} @@ -44,6 +46,15 @@ public void setPageToDelete(@Nullable Point page) { this.pageToDelete = page; } + /** + * Sets the page resource which should be used deleted. + * + * @param pageResource the page resource to set + */ + public void setPageResource(@Nullable PageResource pageResource) { + this.pageResource = pageResource; + } + /** * Returns the survivor marked for deletion. * @@ -61,4 +72,13 @@ public void setPageToDelete(@Nullable Point page) { public @Nullable Point getPageToDelete() { return pageToDelete; } + + /** + * Returns the page resource which should be used deleted. + * + * @return the page resource to delete + */ + public @Nullable PageResource getPageResource() { + return pageResource; + } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/util/PositionFormat.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/util/PositionFormat.java new file mode 100644 index 00000000..31f744ca --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/util/PositionFormat.java @@ -0,0 +1,28 @@ +package net.onelitefeather.cygnus.setup.util; + +import java.math.RoundingMode; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.util.Locale; + +/** + * Helper class to share the same decimal format for all positions. + * + * @author theEvilReaper + * @version 1.0.0 + * @since 2.6.0 + */ +public final class PositionFormat { + + public static final DecimalFormat DECIMAL_FORMAT; + + static { + DECIMAL_FORMAT = new DecimalFormat("#.##"); + DECIMAL_FORMAT.setRoundingMode(RoundingMode.CEILING); + DECIMAL_FORMAT.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ROOT)); + } + + private PositionFormat() { + // Nothing to do here + } +} diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java new file mode 100644 index 00000000..ec103039 --- /dev/null +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java @@ -0,0 +1,46 @@ +package net.onelitefeather.cygnus.setup.data; + +import net.minestom.server.coordinate.Vec; +import net.minestom.server.entity.Player; +import net.minestom.server.instance.Instance; +import net.minestom.server.utils.Direction; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import net.theevilreaper.aves.map.MapEntry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.nio.file.Paths; + +import static org.junit.jupiter.api.Assertions.assertNotNull; + +@ExtendWith(MicrotusExtension.class) +class GameDataTest { + + @Test + void testGameDataCreation(Env env) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(Paths.get("")); + + GameData gameData = new GameData(player, mapEntry); + + assertNotNull(gameData); + + env.destroyInstance(instance, true); + } + + @Test + void testAddAndRemovePage(Env env) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(Paths.get("")); + + GameData gameData = new GameData(player, mapEntry); + + gameData.addPage(Vec.ZERO, Direction.NORTH); + assertNotNull(gameData); + + env.destroyInstance(instance, true); + } +} diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatterTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatterTest.java new file mode 100644 index 00000000..3df33e67 --- /dev/null +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/page/PageHeaderFormatterTest.java @@ -0,0 +1,21 @@ +package net.onelitefeather.cygnus.setup.inventory.page; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +class PageHeaderFormatterTest { + + @Test + void testFormatter() { + Component component = PageHeaderFormatter.format(1, 2); + assertNotNull(component); + + String componentText = PlainTextComponentSerializer.plainText().serialize(component); + + assertNotNull(componentText); + assertEquals("Page 1 of 2", componentText); + } +} diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java index 9ebd8dfc..fd686bbe 100644 --- a/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java @@ -48,7 +48,8 @@ void testPageItemSet(@NotNull Env env) { Player player = env.createPlayer(instance); SetupItems.setPageItems(player); - assertItem(player, 4, (byte) 0x04); + assertItem(player, 2, SetupItemId.PAGES); + assertItem(player, 4, SetupItemId.LEAVE_PAGE); env.destroyInstance(instance, true); }