From d381657fac742a1ce8d4640e3cbb9bbfd73ccf2e Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:14:29 +0200 Subject: [PATCH 01/18] chore(setup): remove command parts which are not required anymore --- .../cygnus/setup/command/SetupCommand.java | 2 -- .../setup/command/parts/SetupNameCommand.java | 35 ------------------ .../command/parts/SetupSpawnCommand.java | 36 ------------------- 3 files changed, 73 deletions(-) delete mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupNameCommand.java delete mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSpawnCommand.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java index 8ab3c738..912e70f6 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java @@ -6,10 +6,8 @@ import net.minestom.server.command.builder.condition.Conditions; import net.onelitefeather.cygnus.common.Messages; import net.onelitefeather.cygnus.setup.command.parts.SetupBuildersCommand; -import net.onelitefeather.cygnus.setup.command.parts.SetupNameCommand; import net.onelitefeather.cygnus.setup.command.parts.SetupPageCommand; import net.onelitefeather.cygnus.setup.command.parts.SetupSlenderSpawnCommand; -import net.onelitefeather.cygnus.setup.command.parts.SetupSpawnCommand; import net.onelitefeather.cygnus.setup.command.parts.SetupSurvivorSpawnCommand; import net.onelitefeather.cygnus.setup.util.SetupData; diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupNameCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupNameCommand.java deleted file mode 100644 index d13ea66d..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupNameCommand.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.onelitefeather.cygnus.setup.command.parts; - -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.arguments.ArgumentType; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.cygnus.setup.util.SetupData; -import net.onelitefeather.cygnus.setup.util.SetupMessages; -import net.onelitefeather.cygnus.setup.util.SetupTags; - -public final class SetupNameCommand extends Command { - - public SetupNameCommand(SetupData setupData) { - super("name"); - setCondition(Conditions::playerOnly); - - var mapName = ArgumentType.String("mapName"); - addSyntax((sender, context) -> { - int ordinalId = sender.getTag(SetupTags.SETUP_ID_TAG); - - if (ordinalId == -1) { - sender.sendMessage(SetupMessages.MISSING_MAP_SELECTION); - return; - } - - String name = context.get(mapName).trim(); - - if (name.isEmpty()) { - sender.sendMessage(SetupMessages.EMPTY_NAME); - return; - } - setupData.getBaseMapBuilder().name(name); - sender.sendMessage("The name of the map now is: " + name); - }, mapName); - } -} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSpawnCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSpawnCommand.java deleted file mode 100644 index 6b4976ec..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSpawnCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -package net.onelitefeather.cygnus.setup.command.parts; - -import net.theevilreaper.aves.util.Components; -import net.kyori.adventure.text.Component; -import net.minestom.server.command.builder.Command; -import net.minestom.server.coordinate.Pos; -import net.minestom.server.entity.Player; -import net.onelitefeather.cygnus.setup.util.SetupData; -import net.onelitefeather.cygnus.setup.util.SetupMessages; -import net.onelitefeather.cygnus.setup.util.SetupTags; - -public final class SetupSpawnCommand extends Command { - - public SetupSpawnCommand(SetupData setupData) { - super("spawn"); - - addSyntax((sender, context) -> { - int ordinalId = sender.getTag(SetupTags.SETUP_ID_TAG); - - if (ordinalId == -1) { - sender.sendMessage(SetupMessages.MISSING_MAP_SELECTION); - return; - } - - if (setupData.hasPageMode()) { - sender.sendMessage(SetupMessages.DISABLED_PAGE_MODE); - return; - } - - Pos position = Pos.fromPoint(((Player) sender).getPosition()); - setupData.getBaseMapBuilder().spawn(position); - var posAsComponent = Components.convertPoint(position); - sender.sendMessage(Component.text("The spawn position of the map is now located at: ").append(posAsComponent)); - }); - } -} From da59e66a89296eecf6ae5040710bdc0e6f2f4d67 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:39:41 +0200 Subject: [PATCH 02/18] chore(setup): improve dialog definition --- .../cygnus/setup/dialogs/AuthorDialogs.java | 72 +++++++++++++++++++ .../cygnus/setup/dialogs/MapDialogs.java | 4 ++ 2 files changed, 76 insertions(+) create mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/AuthorDialogs.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/AuthorDialogs.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/AuthorDialogs.java new file mode 100644 index 00000000..fab343ca --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/AuthorDialogs.java @@ -0,0 +1,72 @@ +package net.onelitefeather.cygnus.setup.dialogs; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.minestom.server.dialog.DialogAction; +import net.minestom.server.dialog.DialogAfterAction; +import net.minestom.server.entity.Player; +import net.onelitefeather.cygnus.setup.util.DialogBase; +import net.onelitefeather.pica.dialog.DialogTemplate; +import net.onelitefeather.pica.dialog.type.DialogType; + +public final class AuthorDialogs extends DialogBase { + + public static final Key AUTHOR_AMOUNT_KEY = create("author_amount_dialog"); + public static final Key AUTHOR_INPUT_ENTRY_KEY = create("author_input_dialog"); + + public static void openAuthorRequestDialog(Player player) { + DialogTemplate dialogTemplate = DialogType.confirm(AUTHOR_AMOUNT_KEY) + .meta(dialogMeta -> { + dialogMeta.closeWithEscape(false); + dialogMeta.pause(false); + dialogMeta.afterAction(DialogAfterAction.CLOSE); + dialogMeta.title(Component.text("Author setup")); + dialogMeta.emptyMessage(); + dialogMeta.messageBody(template -> + template.contents(Component.text("How many builders should the map have?"))); + dialogMeta.range("amount", range -> range + .label(Component.text("Amount")) + .start(1) + .initial(1) + .end(10) + .step(1)); + }) + .yesButton(button -> button.width(100).label(Component.text("Save")) + .action(new DialogAction.DynamicCustom(AUTHOR_AMOUNT_KEY, CompoundBinaryTag.builder().build())) + ) + .noButton(button -> button.width(101).label(Component.text("Cancel"))) + .build(); + dialogTemplate.open(player); + } + + public static void openAuthorInput(Player player, float submitFields) { + DialogTemplate dialogTemplate = DialogType.confirm(AUTHOR_INPUT_ENTRY_KEY) + .meta(dialogMeta -> { + dialogMeta.closeWithEscape(false); + dialogMeta.pause(false); + dialogMeta.afterAction(DialogAfterAction.CLOSE); + dialogMeta.title(Component.text("Author setup")); + dialogMeta.messageBody(template -> + template.contents(Component.text("Please enter the builder(s)"))); + + for (int i = 0; i < submitFields; i++) { + dialogMeta.text("author_" + i, textInputTemplate -> + textInputTemplate.activeLabel(true).label(Component.text("Author: ")).maxLength(32).initial("")); + } + }) + .yesButton(button -> button.width(100).label(Component.text("Save")) + .action(new DialogAction.DynamicCustom(AUTHOR_INPUT_ENTRY_KEY, CompoundBinaryTag.builder() + .putFloat("amount", submitFields) + .build() + )) + ) + .noButton(button -> button.width(101).label(Component.text("Cancel"))) + .build(); + dialogTemplate.open(player); + } + + private AuthorDialogs() { + // Nothing to do here + } +} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/MapDialogs.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/MapDialogs.java index ec628095..afcb30ed 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/MapDialogs.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialogs/MapDialogs.java @@ -14,12 +14,16 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nullable; + /** * */ public final class MapDialogs extends DialogBase { public static final Key MAP_KEY = create("map_name"); + public static final Key AUTHOR_AMOUNT_KEY = create("author_amount_dialog"); + public static final Key AUTHOR_INPUT_ENTRY_KEY = create("author_input_dialog"); + /** * Opens the dialog to allow the input of a name. From e8aa0a40785d42657601672e37f49a5e74fcf177 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:40:20 +0200 Subject: [PATCH 03/18] fix(category): use computeIfAbsent instead of computeIfPresent --- .../net/onelitefeather/cygnus/setup/map/MapDataCategory.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/map/MapDataCategory.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/map/MapDataCategory.java index e8229fc9..7858074a 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/map/MapDataCategory.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/map/MapDataCategory.java @@ -1,5 +1,6 @@ package net.onelitefeather.cygnus.setup.map; +import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import net.minestom.server.item.ItemStack; import net.minestom.server.item.Material; @@ -53,8 +54,9 @@ public static MapDataCategory[] getValues() { * @return the cached item */ public static ItemStack getDefaultItem(MapDataCategory category) { - return DEFAULT_CACHE.computeIfPresent(category, (mapDataCategory, _) -> + return DEFAULT_CACHE.computeIfAbsent(category, mapDataCategory -> ItemStack.builder(mapDataCategory.getMaterial()) + .customName(Component.text(mapDataCategory.name, mapDataCategory.color)) .set(SetupTags.MAP_DATA_CATEGORY_TAG, category) .build()); } From 9da8ef071b19832ed2181c5744b9680f840757b1 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:40:49 +0200 Subject: [PATCH 04/18] chore(setup): add new dialog case handlings --- .../setup/event/dialog/DialogContext.java | 5 +- .../setup/event/dialog/DialogTarget.java | 1 + .../dialog/DialogPayloadListener.java | 50 ++++++++++++++++--- .../dialog/DialogRequestListener.java | 6 +++ 4 files changed, 55 insertions(+), 7 deletions(-) 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 70ac19cc..c24979ef 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 @@ -13,7 +13,8 @@ */ public sealed interface DialogContext permits DialogContext.NameContext, - DialogContext.PositionContent { + DialogContext.PositionContent, + DialogContext.AuthorAmount { /** * Specific context for the update or deletion of a name. @@ -32,4 +33,6 @@ record NameContext(String name) implements DialogContext { record PositionContent(Point point) implements DialogContext { } + + record AuthorAmount(float amount) implements DialogContext {} } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogTarget.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogTarget.java index 0e41ac28..32fe448f 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogTarget.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/dialog/DialogTarget.java @@ -11,6 +11,7 @@ public enum DialogTarget { CREATE_NAME, CREATE_AUTHORS, + AUTHOR_INPUT, UPDATE_NAME, DELETE_NAME, DELETE_SPAWN, diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java index 5dbd2dad..c9a12c16 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java @@ -3,19 +3,28 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.nbt.BinaryTag; import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.nbt.FloatBinaryTag; +import net.kyori.adventure.nbt.IntBinaryTag; import net.kyori.adventure.nbt.StringBinaryTag; +import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.player.PlayerCustomClickEvent; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData; import net.onelitefeather.cygnus.setup.dialogs.MapDialogs; -import net.onelitefeather.cygnus.setup.util.SetupData; +import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; +import net.onelitefeather.cygnus.setup.event.dialog.DialogRequestEvent; +import net.onelitefeather.cygnus.setup.event.dialog.DialogTarget; +import net.onelitefeather.guira.SetupDataService; +import java.util.ArrayList; +import java.util.List; import java.util.function.Consumer; public class DialogPayloadListener implements Consumer { - private final SetupData setupData; + private final SetupDataService dataService; - public DialogPayloadListener(SetupData setupData) { - this.setupData = setupData; + public DialogPayloadListener(SetupDataService dataService) { + this.dataService = dataService; } @Override @@ -30,13 +39,42 @@ public void accept(PlayerCustomClickEvent event) { if (key.equals(MapDialogs.MAP_KEY)) { StringBinaryTag nameBinary = (StringBinaryTag) castedPayload.get("name"); String nameEntry = nameBinary.value(); - if (nameEntry.trim().isBlank()) { return; } + dataService.get(event.getPlayer().getUuid()).ifPresent(data -> { + InstanceSetupData instanceSetupData = (InstanceSetupData) data; + instanceSetupData.getMapBuilder().name(nameEntry); + instanceSetupData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); + }); + } + + if (key.equals(MapDialogs.AUTHOR_AMOUNT_KEY)) { + FloatBinaryTag amountBinary = (FloatBinaryTag) castedPayload.get("amount"); + if (amountBinary == null) return; + float amount = amountBinary.value(); + + if (amount == 0) return; + EventDispatcher.call(new DialogRequestEvent(event.getPlayer(), DialogTarget.AUTHOR_INPUT, new DialogContext.AuthorAmount(amount))); + } + + if (key.equals(MapDialogs.AUTHOR_INPUT_ENTRY_KEY)) { + FloatBinaryTag amountBinary = (FloatBinaryTag) castedPayload.get("amount"); + if (amountBinary == null) return; + + float amount = amountBinary.value(); + + String[] authors = new String[(int) amount]; + for (int i = 0; i < amount; i++) { + authors[i] = castedPayload.getString("author_" + i); + } - this.setupData.getBaseMapBuilder().name(nameEntry); + dataService.get(event.getPlayer().getUuid()).ifPresent(data -> { + InstanceSetupData instanceSetupData = (InstanceSetupData) data; + instanceSetupData.getMapBuilder().builders(authors); + instanceSetupData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); + }); } } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogRequestListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogRequestListener.java index 83d7e8f2..58653fc8 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogRequestListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogRequestListener.java @@ -1,6 +1,7 @@ package net.onelitefeather.cygnus.setup.listener.dialog; import net.minestom.server.entity.Player; +import net.onelitefeather.cygnus.setup.dialogs.AuthorDialogs; import net.onelitefeather.cygnus.setup.dialogs.MapDialogs; import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; import net.onelitefeather.cygnus.setup.event.dialog.DialogRequestEvent; @@ -35,6 +36,11 @@ public void accept(DialogRequestEvent event) { if (context == null) return; MapDialogs.openDeleteDialog(player, MapDataCategory.PAGE, context); } + case CREATE_AUTHORS -> AuthorDialogs.openAuthorRequestDialog(player); + case AUTHOR_INPUT -> { + if (context == null) return; + AuthorDialogs.openAuthorInput(player, ((DialogContext.AuthorAmount)context).amount()); + } default -> { MapDataCategory category = DELETE_TARGETS.get(target); if (category == null || context == null) return; From 27f91d044e2a26bb2cb9ef9b40fce01b04542cf2 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:52:03 +0200 Subject: [PATCH 05/18] chore(setup): improve layout definition --- .../cygnus/setup/item/SetupItems.java | 41 +++++++++++++++---- .../cygnus/setup/item/SetupItemsTest.java | 2 +- 2 files changed, 33 insertions(+), 10 deletions(-) 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 e16e0fea..be921d58 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 @@ -23,7 +23,8 @@ public final class SetupItems { public static final byte FOURTH_INDEX = (byte) 0x04; private static final HotBarLayout selectionLayout; - private static final HotBarLayout mapLayout; + private static final HotBarLayout lobbySetupLayout; + private static final HotBarLayout gameSetupLayout; private static final HotBarLayout pageLayout; static { @@ -38,21 +39,33 @@ public final class SetupItems { .customName(Component.text("Save data", NamedTextColor.RED)) .set(Tags.ITEM_TAG, (byte) 0x01) .build(); - mapLayout = new HotBarLayout(); - mapLayout.set(2, ItemStack.builder(Material.COMPASS) + lobbySetupLayout = new HotBarLayout(); + lobbySetupLayout.set(2, ItemStack.builder(Material.COMPASS) .customName(Component.text("Data", NamedTextColor.AQUA)) .set(Tags.ITEM_TAG, (byte) 0x02) .build() ); - mapLayout.set(6, saveItem); + lobbySetupLayout.set(6, saveItem); + + gameSetupLayout = new HotBarLayout(); + gameSetupLayout.set(2, ItemStack.builder(Material.COMPASS) + .customName(Component.text("Data", NamedTextColor.AQUA)) + .set(Tags.ITEM_TAG, (byte) 0x02) + .build() + ); + gameSetupLayout.set(4, ItemStack.builder(Material.PAPER) + .customName(Component.text("Page", NamedTextColor.AQUA)) + .set(Tags.ITEM_TAG, (byte) 0x03) + .build() + ); + gameSetupLayout.set(6, saveItem); pageLayout = new HotBarLayout(); pageLayout.set(2, ItemStack.builder(Material.BARRIER) - .customName(Component.text("Cancel", NamedTextColor.RED)) - .set(Tags.ITEM_TAG, (byte) 0x03) + .customName(Component.text("Leave page mode", NamedTextColor.RED)) + .set(Tags.ITEM_TAG, (byte) 0x04) .build() ); - pageLayout.set(6, saveItem); } /** @@ -70,11 +83,21 @@ public static void setMapSelection(Player player) { * * @param player the player who should receive the item */ - public static void setSaveData(Player player) { - mapLayout.apply(player); + public static void setLobbyLayout(Player player) { + lobbySetupLayout.apply(player); player.setHeldItemSlot(ZERO_INDEX); } + /** + * Set's the {@link ItemStack} which are required for the game setup. + * + * @param player who should receive the items + */ + public static void setGameLayout(Player player) { + gameSetupLayout.apply(player); + player.setHeldItemSlot(FOURTH_INDEX); + } + /** * Set's the {@link ItemStack} which are required for the page setup. * 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 15d12f93..743f2042 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 @@ -35,7 +35,7 @@ void testSaveDataItemSet(@NotNull Env env) { Instance instance = env.createFlatInstance(); Player player = env.createPlayer(instance); - SetupItems.setSaveData(player); + SetupItems.setLobbyLayout(player); assertItem(player, 2, (byte) 0x02); assertItem(player, 6, (byte) 0x01); From 94e3fa0694253a666267c42a013fc26c50d863ba Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:56:40 +0200 Subject: [PATCH 06/18] chore(setup): improve item interaction handling --- .../setup/listener/SetupItemListener.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SetupItemListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SetupItemListener.java index 1a74f6ea..54891956 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SetupItemListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SetupItemListener.java @@ -1,23 +1,27 @@ package net.onelitefeather.cygnus.setup.listener; import net.minestom.server.event.EventDispatcher; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData; import net.onelitefeather.cygnus.setup.event.MapSetupSaveEvent; import net.minestom.server.event.player.PlayerUseItemEvent; import net.onelitefeather.cygnus.common.Tags; import net.onelitefeather.cygnus.setup.inventory.MapSetupInventory; -import net.onelitefeather.cygnus.setup.util.SetupData; import net.onelitefeather.cygnus.setup.item.SetupItems; +import net.onelitefeather.cygnus.setup.util.SetupMessages; import net.onelitefeather.cygnus.setup.util.SetupTags; +import net.onelitefeather.guira.SetupDataService; +import java.util.Set; import java.util.function.Consumer; public final class SetupItemListener implements Consumer { - private final SetupData setupData; + private final SetupDataService dataService; private final MapSetupInventory mapSetupInventory; - public SetupItemListener(SetupData setupData, MapSetupInventory mapSetupInventory) { - this.setupData = setupData; + public SetupItemListener(SetupDataService dataService, MapSetupInventory mapSetupInventory) { + this.dataService = dataService; this.mapSetupInventory = mapSetupInventory; } @@ -29,13 +33,19 @@ public void accept(PlayerUseItemEvent event) { byte tagValue = event.getItemStack().getTag(Tags.ITEM_TAG); if (1 == tagValue && player.hasTag(SetupTags.SETUP_ID_TAG)) { - EventDispatcher.call(new MapSetupSaveEvent(player, setupData)); + EventDispatcher.call(new MapSetupSaveEvent(player)); return; } // Check if the given tag value is 0 which represents the item for the map selection - if (SetupItems.ZERO_INDEX == tagValue && !setupData.hasMap()) { + if (SetupItems.ZERO_INDEX == tagValue) { mapSetupInventory.open(player); } + + if (!player.hasTag(SetupTags.SETUP_ID_TAG)) return; + + this.dataService.get(player.getUuid()).ifPresent(data -> + ((InstanceSetupData) data).handleItemInteraction(player, tagValue)); + } } From e0c162d5f822ef894eb662c17ccd89f9cebd7316 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:57:05 +0200 Subject: [PATCH 07/18] chore(setup): improve inventory creation and add item handling --- .../cygnus/setup/data/GameData.java | 52 +++++++++++++------ .../cygnus/setup/data/InstanceSetupData.java | 4 ++ .../cygnus/setup/data/LobbyData.java | 14 +++-- 3 files changed, 45 insertions(+), 25 deletions(-) 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 1c8c4bab..3fe4ea22 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 @@ -8,9 +8,10 @@ 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.view.GeneralMapOverviewInventory; +import net.onelitefeather.cygnus.setup.inventory.view.MapDataOveriewInventory; import net.onelitefeather.cygnus.setup.inventory.view.SurvivorViewInventory; -import net.theevilreaper.aves.file.FileHandler; +import net.onelitefeather.cygnus.setup.item.SetupItems; +import net.onelitefeather.cygnus.setup.util.SetupMessages; import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; @@ -20,37 +21,35 @@ public class GameData extends InstanceSetupData { - private final FileHandler fileHandler; - private final GeneralMapOverviewInventory inventory; + private final MapDataOveriewInventory inventory; private final SurvivorViewInventory survivorInventory; private GameMapBuilder gameMapBuilder; - private boolean areaMode; + private boolean pageMode; /** * Constructs a new GameData instance. * * @param uuid the UUID of the player * @param mapEntry the map entry associated with this game data - * @param fileHandler the file handler for saving and loading game data */ - public GameData(UUID uuid, MapEntry mapEntry, FileHandler fileHandler) { + public GameData(UUID uuid, MapEntry mapEntry) { super(uuid, mapEntry, BossBar.Color.RED); - this.fileHandler = fileHandler; Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(uuid); this.loadData(); if (player == null) { throw new IllegalArgumentException("Player with UUID " + uuid + " is not online."); } - this.inventory = new GeneralMapOverviewInventory(player, this.gameMapBuilder); + System.out.println("After loadData: " + System.identityHashCode(this.gameMapBuilder)); + this.inventory = new MapDataOveriewInventory(player, this.gameMapBuilder); this.survivorInventory = new SurvivorViewInventory(player, this.gameMapBuilder); } /** * Swaps between area mode and normal mode. */ - public void swapAreaMode() { - this.areaMode = !this.areaMode; + public void swapPageMode() { + this.pageMode = !this.pageMode; } /** @@ -81,6 +80,26 @@ public void triggerUpdate(InventoryTarget target) { } } + @Override + public void handleItemInteraction(Player player, byte tagValue) { + if (3 == tagValue) { + swapPageMode(); + if (hasPageMode()) { + player.sendMessage(SetupMessages.PAGE_MODE_ENABLED); + player.sendMessage(SetupMessages.PAGE_MODE_INFORM); + } + SetupItems.setPageItems(player); + return; + } + if (4 == tagValue) { + swapPageMode(); + player.sendMessage(SetupMessages.PAGE_MODE_DISABLED); + SetupItems.setGameLayout(player); + return; + } + super.handleItemInteraction(player, tagValue); + } + /** * {@inheritDoc} */ @@ -109,7 +128,6 @@ public void reset() { super.reset(); this.survivorInventory.unregister(); this.inventory.unregister(); - // this.inventory.unregister(); } /** @@ -120,7 +138,7 @@ public void loadData() { if (!this.mapEntry.hasMapFile()) { this.gameMapBuilder = new GameMapBuilder(); } else { - Optional mapData = fileHandler.load(mapEntry.getMapFile(), GameMap.class); + Optional mapData = GsonHelper.FILE_HANDLER.load(mapEntry.getMapFile(), GameMap.class); mapData.ifPresentOrElse(gameMap -> this.gameMapBuilder = new GameMapBuilder(gameMap), () -> this.gameMapBuilder = new GameMapBuilder() @@ -135,12 +153,12 @@ public void loadData() { } /** - * Returns an indication if the area mode is active or not. + * Returns an indication if the page mode is active or not. * - * @return true if area mode is active, false otherwise + * @return true if page mode is active, false otherwise */ - public boolean hasAreaMode() { - return areaMode; + public boolean hasPageMode() { + return pageMode; } /** diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java index 29529643..2ea14de0 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java @@ -80,6 +80,10 @@ public void teleport(Player player) { */ public abstract void triggerUpdate(InventoryTarget target); + public void handleItemInteraction(Player player, byte tagValue) { + openInventory(InventoryTarget.GENERAL); + } + /** * Checks whether a map file is available for this setup. * diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java index 1e20fcdc..5b051498 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java @@ -5,8 +5,8 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.anvil.AnvilLoader; -import net.onelitefeather.cygnus.setup.inventory.view.GeneralMapOverviewInventory; -import net.theevilreaper.aves.file.FileHandler; +import net.onelitefeather.cygnus.common.util.GsonHelper; +import net.onelitefeather.cygnus.setup.inventory.view.MapDataOveriewInventory; import net.theevilreaper.aves.inventory.PersonalInventoryBuilder; import net.theevilreaper.aves.map.BaseMap; import net.theevilreaper.aves.map.BaseMapBuilder; @@ -18,13 +18,11 @@ public final class LobbyData extends InstanceSetupData { - private final FileHandler fileHandler; private final PersonalInventoryBuilder viewInventory; private BaseMapBuilder mapBuilder; - public LobbyData(UUID uuid, MapEntry mapEntry, FileHandler fileHandler) { + public LobbyData(UUID uuid, MapEntry mapEntry) { super(uuid, mapEntry, BossBar.Color.GREEN); - this.fileHandler = fileHandler; this.loadData(); Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(uuid); @@ -32,7 +30,7 @@ public LobbyData(UUID uuid, MapEntry mapEntry, FileHandler fileHandler) { throw new IllegalArgumentException("Player with UUID " + uuid + " is not online."); } - this.viewInventory = new GeneralMapOverviewInventory(player, this.mapBuilder); + this.viewInventory = new MapDataOveriewInventory(player, this.mapBuilder); } @Override @@ -50,7 +48,7 @@ public void save() { if (!Files.exists(mapEntry.getMapFile())) { this.mapEntry.createFile(); } - this.fileHandler.save(mapEntry.getMapFile(), BaseMap.class); + GsonHelper.FILE_HANDLER.save(mapEntry.getMapFile(), BaseMap.class); } @Override @@ -73,7 +71,7 @@ public void loadData() { if (this.mapEntry == null) { this.mapBuilder = BaseMap.builder(); } else { - Optional mapData = fileHandler.load(mapEntry.getMapFile(), BaseMap.class); + Optional mapData = GsonHelper.FILE_HANDLER.load(mapEntry.getMapFile(), BaseMap.class); mapData.ifPresentOrElse(baseMap -> { this.mapBuilder = BaseMap.builder(baseMap); From 9b6bdb2a7713e64d67cb64b64f5a11cf4ee84dca Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:57:35 +0200 Subject: [PATCH 08/18] chore(setup): remove builders and page mode command --- .../cygnus/setup/command/SetupCommand.java | 2 - .../command/parts/SetupBuildersCommand.java | 65 ------------------- .../setup/command/parts/SetupPageCommand.java | 45 ------------- 3 files changed, 112 deletions(-) delete mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupBuildersCommand.java delete mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupPageCommand.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java index 912e70f6..8288b5d6 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java @@ -5,8 +5,6 @@ import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.condition.Conditions; import net.onelitefeather.cygnus.common.Messages; -import net.onelitefeather.cygnus.setup.command.parts.SetupBuildersCommand; -import net.onelitefeather.cygnus.setup.command.parts.SetupPageCommand; import net.onelitefeather.cygnus.setup.command.parts.SetupSlenderSpawnCommand; import net.onelitefeather.cygnus.setup.command.parts.SetupSurvivorSpawnCommand; import net.onelitefeather.cygnus.setup.util.SetupData; diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupBuildersCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupBuildersCommand.java deleted file mode 100644 index c120c142..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupBuildersCommand.java +++ /dev/null @@ -1,65 +0,0 @@ -package net.onelitefeather.cygnus.setup.command.parts; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.JoinConfiguration; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.arguments.ArgumentType; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.cygnus.setup.util.SetupData; -import net.onelitefeather.cygnus.setup.util.SetupMessages; -import net.onelitefeather.cygnus.setup.util.SetupTags; - -import java.util.Arrays; -import java.util.List; - -/** - * The command allows the set the creators of a map to a {@link net.theevilreaper.aves.map.BaseMap} reference. - * - * @author theEvilReaper - * @version 1.0.0 - * @since 1.0.0 - */ -public final class SetupBuildersCommand extends Command { - - /** - * Creates a new instance from the command class and contains also the logic to execute the command. - * - * @param setupData the involved {@link SetupData} class to get some information from it - */ - public SetupBuildersCommand(SetupData setupData) { - super("builders"); - setCondition(Conditions::playerOnly); - - var buildersArray = ArgumentType.StringArray("builders"); - - addSyntax((sender, context) -> { - int ordinalId = sender.getTag(SetupTags.SETUP_ID_TAG); - - if (ordinalId == -1) { - sender.sendMessage(SetupMessages.MISSING_MAP_SELECTION); - return; - } - String[] builders = context.get(buildersArray); - - if (builders.length == 0) { - sender.sendMessage(Component.text("A map needs at least one builder", NamedTextColor.RED)); - return; - } - setupData.getBaseMapBuilder().builders(builders); - var buildersAsComponent = Component.join(JoinConfiguration.arrayLike(), transformBuilders(builders)); - sender.sendMessage(Component.text("The creators of the map are: ").append(buildersAsComponent)); - }, buildersArray); - } - - /** - * Transforms the given builders into a {@link TextComponent} list. - * - * @param builders the builders to transform - * @return a list with the transformed builders - */ - private List transformBuilders(String... builders) { - return Arrays.stream(builders).map(Component::text).toList(); - } -} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupPageCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupPageCommand.java deleted file mode 100644 index 9c4cfb75..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupPageCommand.java +++ /dev/null @@ -1,45 +0,0 @@ -package net.onelitefeather.cygnus.setup.command.parts; - -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.cygnus.setup.util.SetupData; -import net.onelitefeather.cygnus.setup.util.SetupMessages; -import net.onelitefeather.cygnus.setup.util.SetupMode; -import net.onelitefeather.cygnus.setup.util.SetupTags; - -/** - * @author theEvilReaper - * @version 1.0.0 - * @since - **/ -public final class SetupPageCommand extends Command { - - public SetupPageCommand(SetupData setupData) { - super("page"); - setCondition(Conditions::playerOnly); - - addSyntax((sender, context) -> { - int ordinalId = sender.getTag(SetupTags.SETUP_ID_TAG); - - if (ordinalId == -1) { - sender.sendMessage(SetupMessages.MISSING_MAP_SELECTION); - return; - } - - if (!SetupMode.isMode(SetupMode.GAME, ordinalId)) { - sender.sendMessage(SetupMessages.getInvalidModeDuringLobby("page")); - return; - } - - setupData.swapPageMode(); - - if (setupData.hasPageMode()) { - sender.sendMessage(SetupMessages.PAGE_MODE_ENABLED); - sender.sendMessage(SetupMessages.PAGE_MODE_INFORM); - return; - } - - sender.sendMessage(SetupMessages.PAGE_MODE_DISABLED); - }); - } -} From 605bf808e08a1aba37aba0bc62c7f6e441180a98 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:57:45 +0200 Subject: [PATCH 09/18] chore(setup): remove old SetupData approach --- .../cygnus/setup/util/SetupData.java | 166 ------------------ .../cygnus/setup/util/SetupDataTest.java | 43 ----- 2 files changed, 209 deletions(-) delete mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupData.java delete mode 100644 setup/src/test/java/net/onelitefeather/cygnus/setup/util/SetupDataTest.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupData.java deleted file mode 100644 index 32ef971f..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupData.java +++ /dev/null @@ -1,166 +0,0 @@ -package net.onelitefeather.cygnus.setup.util; - -import net.onelitefeather.cygnus.common.map.GameMapBuilder; -import net.theevilreaper.aves.map.BaseMap; -import net.kyori.adventure.bossbar.BossBar; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.TextComponent; -import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.MinecraftServer; -import net.minestom.server.coordinate.Pos; -import net.minestom.server.entity.Player; -import net.minestom.server.instance.InstanceContainer; -import net.minestom.server.instance.anvil.AnvilLoader; -import net.theevilreaper.aves.map.BaseMapBuilder; -import net.theevilreaper.aves.map.MapEntry; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; - -/** - * The {@link SetupData} is a class which stores different data about a setup process. - * Compared to other setup modes in other games it allows to have multiple maps in the setup. - * To avoid issue during these specific session each setup has its own data to store important data - * - * @author theEvilReaper - * @version 1.0.0 - * @since 1.0.0 - */ -@Deprecated(forRemoval = true) -public final class SetupData { - - private static final Pos SPAWN_POINT = new Pos(0, 100, 0); - - private MapEntry selectedMap; - private SetupMode setupMode; - private BaseMapBuilder baseMapBuilder; - - private InstanceContainer instance; - private boolean pageMode; - - private BossBar bossBar; - - public SetupData() { - this.bossBar = BossBar.bossBar(Component.empty(), 1, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS); - } - - /** - * Updates the mode for the selection process. - * - * @param setupMode the mode to set - */ - public void setSetupMode(@NotNull SetupMode setupMode) { - if (this.setupMode != null) return; - this.setupMode = setupMode; - this.baseMapBuilder = setupMode == SetupMode.LOBBY ? BaseMap.builder() : new GameMapBuilder(); - } - - /** - * Updates the current sub mode to the page setup - */ - public void swapPageMode() { - if (this.setupMode == SetupMode.LOBBY) return; - this.pageMode = !this.pageMode; - } - - /** - * Updates the selected map entry for the setup - * - * @param selectedMap the new map which should receive their setup - */ - public void setSelectedMap(@NotNull MapEntry selectedMap) { - if (this.selectedMap != null) return; - this.selectedMap = selectedMap; - TextComponent title = Component.text("Setup mode: ") - .append(Component.text(setupMode.name(), NamedTextColor.LIGHT_PURPLE)) - .append(Component.text(", Map: ")) - .append(Component.text(selectedMap.getDirectoryRoot().getFileName().toString(), NamedTextColor.LIGHT_PURPLE)); - this.bossBar.name(title); - } - - /** - * Resets the given data from the setup. - * It also removes the underlying {@link InstanceContainer} which holds the loaded world. - * When the method is invoked the map will be unloaded by the system. - */ - public void reset() { - this.selectedMap = null; - this.setupMode = null; - MinecraftServer.getInstanceManager().unregisterInstance(this.instance); - this.bossBar = null; - } - - /** - * Removes the boss bar from the given player. - * - * @param player the player to remove the boss bar - */ - public void removeBossBar(@NotNull Player player) { - player.hideBossBar(this.bossBar); - } - - /** - * Loads the given data from the map into the setup reference. - */ - public void loadMap() { - AnvilLoader anvilLoader = new AnvilLoader(this.selectedMap.getDirectoryRoot()); - this.instance = MinecraftServer.getInstanceManager().createInstanceContainer(); - this.instance.setChunkLoader(anvilLoader); - MinecraftServer.getInstanceManager().registerInstance(this.instance); - } - - /** - * Returns an indicator if the reference contains a map for the setup. - * - * @return true when yes otherwise false - */ - public boolean hasMap() { - return this.selectedMap != null; - } - - /** - * Returns if the page setup mode is activated or not. - * - * @return true when its active otherwise false - */ - public boolean hasPageMode() { - return pageMode; - } - - /** - * Teleports a {@link Player} to the {@link net.minestom.server.instance.Instance} which is used for the setup. - * - * @param player the player to teleport - */ - public void teleport(@NotNull Player player) { - player.setInstance(this.instance, SPAWN_POINT); - player.showBossBar(this.bossBar); - } - - /** - * Returns a {@link MapEntry} which represents the selected map for the setup process. - * - * @return the given selected map if present otherwise null - */ - public @Nullable MapEntry getSelectedMap() { - return selectedMap; - } - - /** - * Returns the given instance from a {@link BaseMap}. - * - * @return the underlying reference or null - */ - public @Nullable BaseMapBuilder getBaseMapBuilder() { - return baseMapBuilder; - } - - /** - * Returns the given {@link SetupMode} reference. - * - * @return the given reference from the mode or null - */ - public @UnknownNullability SetupMode getSetupMode() { - return setupMode; - } -} diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/util/SetupDataTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/util/SetupDataTest.java deleted file mode 100644 index 5614f22e..00000000 --- a/setup/src/test/java/net/onelitefeather/cygnus/setup/util/SetupDataTest.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.onelitefeather.cygnus.setup.util; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -class SetupDataTest { - - @Test - void testSetupDataWithNoData() { - SetupData setupData = new SetupData(); - assertNotNull(setupData); - assertFalse(setupData.hasPageMode()); - assertNull(setupData.getSelectedMap()); - assertNull(setupData.getBaseMapBuilder()); - assertNull(setupData.getSetupMode()); - } - - @Test - void testSetupModeChangeInData() { - SetupData setupData = new SetupData(); - assertNotNull(setupData); - assertNull(setupData.getSetupMode()); - setupData.setSetupMode(SetupMode.GAME); - assertNotNull(setupData.getSetupMode()); - assertEquals(SetupMode.GAME, setupData.getSetupMode()); - } - - @Test - void testSetupDataWithPageContext() { - SetupData setupData = new SetupData(); - assertNotNull(setupData); - assertFalse(setupData.hasPageMode()); - - setupData.swapPageMode(); - - assertTrue(setupData.hasPageMode()); - } -} From 3fc7e046542e24516b30a3212117ec994a7cc525 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:58:36 +0200 Subject: [PATCH 10/18] chore(setup): better null handling --- .../cygnus/setup/inventory/slot/PositionSlot.java | 14 ++++++++++++-- .../cygnus/setup/inventory/slot/StringSlot.java | 9 +++------ 2 files changed, 15 insertions(+), 8 deletions(-) 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 e6700ee8..886e6683 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 @@ -7,6 +7,7 @@ import net.minestom.server.event.EventDispatcher; import net.minestom.server.inventory.click.Click; import net.minestom.server.item.ItemStack; +import net.onelitefeather.cygnus.setup.event.PositionSetEvent; import net.onelitefeather.cygnus.setup.event.dialog.DialogContext; import net.onelitefeather.cygnus.setup.event.dialog.DialogRequestEvent; import net.onelitefeather.cygnus.setup.event.dialog.DialogTarget; @@ -64,12 +65,21 @@ public ItemStack getItem() { @Override protected void click(Player player, int slot, Click click, ItemStack stack, Consumer result) { result.accept(ClickHolder.cancelClick()); - if ((!(click instanceof Click.Left || click instanceof Click.Right)) || position == null) return; + + if (position == null && click instanceof Click.Left) { + EventDispatcher.call(new PositionSetEvent(player, player.getPosition(), type)); + return; + } + if (click instanceof Click.Left) { player.closeInventory(); player.teleport(position); return; } - EventDispatcher.call(new DialogRequestEvent(player, DialogTarget.DELETE_SPAWN, new DialogContext.PositionContent(position))); + + if (click instanceof Click.Right) { + EventDispatcher.call(new DialogRequestEvent(player, DialogTarget.DELETE_SPAWN, new DialogContext.PositionContent(position))); + + } } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/StringSlot.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/StringSlot.java index b4d26df1..1f35b72a 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/StringSlot.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/slot/StringSlot.java @@ -9,7 +9,6 @@ import net.onelitefeather.cygnus.setup.event.dialog.DialogTarget; import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.theevilreaper.aves.inventory.click.ClickHolder; -import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -20,7 +19,7 @@ public class StringSlot extends AbstractDataSlot { private final String data; - public StringSlot(MapDataCategory category, @Nullable String data) { + public StringSlot(MapDataCategory category, String data) { super(category); this.data = data; } @@ -29,9 +28,7 @@ public StringSlot(MapDataCategory category, @Nullable String data) { public ItemStack getItem() { ItemStack overviewItem = MapDataCategory.getDefaultItem(type); - if (data == null) { - return overviewItem; - } + if (data.equals("Map")) return overviewItem; return asBuilder(overviewItem).lore( Component.empty(), NO_SPACE_SEPARATOR.append(Component.space()).append(Component.text(data, type.getColor())), @@ -46,7 +43,7 @@ public ItemStack getItem() { protected void click(Player player, int slot, Click click, ItemStack stack, Consumer result) { result.accept(ClickHolder.cancelClick()); - if (data == null || data.isEmpty()) { + if (data.equals("Map")) { EventDispatcher.call(new DialogRequestEvent(player, DialogTarget.CREATE_NAME)); return; } From 84f1bcf23ef1186859e4fe6d964866f8031fc49d Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:58:52 +0200 Subject: [PATCH 11/18] feat(setup): add position set event and listener --- .../cygnus/setup/event/PositionSetEvent.java | 32 ++++++++++ .../position/PositionSetListener.java | 58 +++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/event/PositionSetEvent.java create mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/PositionSetEvent.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/PositionSetEvent.java new file mode 100644 index 00000000..094b5f68 --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/PositionSetEvent.java @@ -0,0 +1,32 @@ +package net.onelitefeather.cygnus.setup.event; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.server.event.trait.PlayerEvent; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; + +public class PositionSetEvent implements PlayerEvent { + + private final Player player; + private final Pos pos; + private final MapDataCategory category; + + public PositionSetEvent(Player player, Pos pos, MapDataCategory category) { + this.player = player; + this.pos = pos; + this.category = category; + } + + @Override + public Player getPlayer() { + return this.player; + } + + public Pos getPos() { + return this.pos; + } + + public MapDataCategory getCategory() { + return this.category; + } +} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java new file mode 100644 index 00000000..5eb7d11d --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java @@ -0,0 +1,58 @@ +package net.onelitefeather.cygnus.setup.listener.position; + +import net.onelitefeather.cygnus.common.map.GameMapBuilder; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData; +import net.onelitefeather.cygnus.setup.data.LobbyData; +import net.onelitefeather.cygnus.setup.event.PositionSetEvent; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import net.onelitefeather.guira.SetupDataService; +import net.onelitefeather.guira.data.SetupData; + +import java.util.Optional; +import java.util.function.Consumer; + +public class PositionSetListener implements Consumer { + + private final SetupDataService dataService; + + public PositionSetListener(SetupDataService dataService) { + this.dataService = dataService; + } + + @Override + public void accept(PositionSetEvent event) { + MapDataCategory category = event.getCategory(); + + Optional optionalSetupData = this.dataService.get(event.getPlayer().getUuid()); + + if (optionalSetupData.isEmpty()) return; + + switch (optionalSetupData.get()) { + case LobbyData lobbyData -> { + lobbyData.getMapBuilder().spawn(event.getPos()); + lobbyData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); + } + case GameData gameData -> { + switch (category) { + case SPAWN -> { + gameData.getMapBuilder().spawn(event.getPos()); + gameData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); + + } + case SLENDER -> { + ((GameMapBuilder) gameData.getMapBuilder()).setSlenderSpawn(event.getPos()); + } + default -> { + // Nothing to do here + } + } + } + default -> { + // Nothing to do here + } + } + + + } +} From aef606895afe3ea84fcadb010d9882f2bf08c43b Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:59:20 +0200 Subject: [PATCH 12/18] feat(setup): migrate SetupData usage --- .../cygnus/setup/event/MapSetupSaveEvent.java | 15 +-------- .../listener/MapSetupSelectListener.java | 33 ++++++++++++------- .../setup/listener/PageCreationListener.java | 23 +++++++++---- .../listener/map/MapSetupSaveListener.java | 7 ++-- 4 files changed, 44 insertions(+), 34 deletions(-) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/MapSetupSaveEvent.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/MapSetupSaveEvent.java index 345bdc5c..6fee90de 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/event/MapSetupSaveEvent.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/event/MapSetupSaveEvent.java @@ -2,7 +2,6 @@ import net.minestom.server.entity.Player; import net.minestom.server.event.trait.PlayerEvent; -import net.onelitefeather.cygnus.setup.util.SetupData; /** * Called when a {@link Player} wants to save the data from a map. @@ -14,26 +13,14 @@ public final class MapSetupSaveEvent implements PlayerEvent { private final Player player; - private final SetupData setupData; /** * Creates a new instance of the event with the given parameters. * * @param player which is involved - * @param setupData which contains the data to save */ - public MapSetupSaveEvent(Player player, SetupData setupData) { + public MapSetupSaveEvent(Player player) { this.player = player; - this.setupData = setupData; - } - - /** - * Returns the {@link SetupData} associated with this event. - * - * @return associated data - */ - public SetupData getSetupData() { - return this.setupData; } /** diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/MapSetupSelectListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/MapSetupSelectListener.java index a1b2cfc3..cb1da604 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/MapSetupSelectListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/MapSetupSelectListener.java @@ -5,50 +5,61 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; import net.onelitefeather.cygnus.common.Messages; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData; +import net.onelitefeather.cygnus.setup.data.LobbyData; import net.onelitefeather.cygnus.setup.event.MapSetupSelectEvent; -import net.onelitefeather.cygnus.setup.util.SetupData; import net.onelitefeather.cygnus.setup.util.SetupTags; +import net.onelitefeather.guira.SetupDataService; +import net.onelitefeather.guira.data.SetupData; import java.time.Duration; import java.time.temporal.ChronoUnit; +import java.util.Optional; import java.util.function.Consumer; public final class MapSetupSelectListener implements Consumer { private final Component alreadySelected; private final Component loadingMessage; - private final SetupData setupData; + private final SetupDataService dataService; - public MapSetupSelectListener(SetupData setupData) { + public MapSetupSelectListener(SetupDataService dataService) { this.alreadySelected = Messages.withPrefix(Component.text("You already selected a map", NamedTextColor.RED)); this.loadingMessage = Messages.withPrefix(Component.text("Loading world please wait...", NamedTextColor.GRAY)); - this.setupData = setupData; + this.dataService = dataService; } @Override public void accept(MapSetupSelectEvent event) { Player player = event.getPlayer(); - if (setupData.hasMap()) { + + Optional optionalSetupData = this.dataService.get(player.getUuid()); + + if (optionalSetupData.isPresent()) { player.sendMessage(this.alreadySelected); event.setCancelled(true); return; } - setupData.setSetupMode(event.getSetupMode()); - setupData.setSelectedMap(event.getMapEntry()); + SetupData setupData = switch (event.getSetupMode()) { + case GAME -> new GameData(player.getUuid(), event.getMapEntry()); + case LOBBY -> new LobbyData(player.getUuid(), event.getMapEntry()); + }; + player.setTag(SetupTags.SETUP_ID_TAG, event.getSetupMode().ordinal()); Component message = Messages.withPrefix(Component.text("You selected the map: ", NamedTextColor.GRAY)) .append(Component.text(event.getMapEntry().getDirectoryRoot().getFileName().toString(), NamedTextColor.AQUA)); player.sendMessage(message); player.sendMessage(this.loadingMessage); - setupData.loadMap(); player.getInventory().clear(); - MinecraftServer.getSchedulerManager().buildTask(() -> handleTeleport(event.getPlayer())) + this.dataService.add(player.getUuid(), setupData); + MinecraftServer.getSchedulerManager().buildTask(() -> handleTeleport(event.getPlayer(), setupData)) .delay(Duration.of(3, ChronoUnit.SECONDS)) .schedule(); } - private void handleTeleport(Player player) { - setupData.teleport(player); + private void handleTeleport(Player player, SetupData setupData) { + ((InstanceSetupData) setupData).teleport(player); } } 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 a688a576..276e15df 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 @@ -1,6 +1,10 @@ package net.onelitefeather.cygnus.setup.listener; import net.onelitefeather.cygnus.common.map.GameMapBuilder; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.util.SetupTags; +import net.onelitefeather.guira.SetupDataService; +import net.onelitefeather.guira.data.SetupData; import net.theevilreaper.aves.util.Components; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -11,18 +15,16 @@ import net.minestom.server.utils.Direction; import net.minestom.server.utils.MathUtils; import net.onelitefeather.cygnus.common.Messages; -import net.onelitefeather.cygnus.common.map.GameMap; import net.onelitefeather.cygnus.common.util.DirectionFaceHelper; -import net.onelitefeather.cygnus.setup.util.SetupData; import net.onelitefeather.cygnus.setup.util.SetupMessages; import java.util.function.Consumer; public final class PageCreationListener implements Consumer { - private final SetupData setupData; + private final SetupDataService setupData; - public PageCreationListener(SetupData setupData) { + public PageCreationListener(SetupDataService setupData) { this.setupData = setupData; } @@ -30,9 +32,16 @@ public PageCreationListener(SetupData setupData) { public void accept(PlayerBlockBreakEvent event) { event.setCancelled(true); - if (setupData.getBaseMapBuilder() == null || !setupData.hasPageMode()) return; - Player player = event.getPlayer(); + + if (!player.hasTag(SetupTags.SETUP_ID_TAG)) return; + + SetupData setupData = this.setupData.get(player.getUuid()).orElse(null); + + if (setupData == null) return; + + if (!(setupData instanceof GameData gameData) || !gameData.hasPageMode()) return; + Direction direction = MathUtils.getHorizontalDirection(player.getPosition().yaw()); Vec dir = player.getPosition().direction(); @@ -46,7 +55,7 @@ public void accept(PlayerBlockBreakEvent event) { } Vec position = event.getBlockPosition().asVec(); - ((GameMapBuilder) setupData.getBaseMapBuilder()).addPage(position, direction); + ((GameMapBuilder) gameData.getMapBuilder()).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/map/MapSetupSaveListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java index 897eea7a..e3e667ee 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java @@ -2,22 +2,25 @@ import net.minestom.server.MinecraftServer; import net.onelitefeather.cygnus.setup.event.MapSetupSaveEvent; +import net.onelitefeather.guira.SetupDataService; import net.theevilreaper.aves.util.functional.PlayerConsumer; import java.util.function.Consumer; public class MapSetupSaveListener implements Consumer { + private final SetupDataService dataService; private final PlayerConsumer teleportBackLogic; - public MapSetupSaveListener(PlayerConsumer teleportBackLogic) { + public MapSetupSaveListener(SetupDataService dataService, PlayerConsumer teleportBackLogic) { this.teleportBackLogic = teleportBackLogic; + this.dataService = dataService; } @Override public void accept(MapSetupSaveEvent event) { //TODO: add save back this.teleportBackLogic.accept(event.getPlayer()); - MinecraftServer.getSchedulerManager().scheduleNextTick(event.getSetupData()::reset); + MinecraftServer.getSchedulerManager().scheduleNextTick(dataService.get(event.getPlayer().getUuid()).get()::reset); } } From 7961a65f061f0c88a0e7121f2d173bc3c98e12ee Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 15:59:32 +0200 Subject: [PATCH 13/18] feat(setup): update item handling --- .../setup/listener/InstanceAddListener.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/InstanceAddListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/InstanceAddListener.java index 032cd6e4..e5412d9c 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/InstanceAddListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/InstanceAddListener.java @@ -4,6 +4,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.event.instance.AddEntityToInstanceEvent; import net.onelitefeather.cygnus.setup.item.SetupItems; +import net.onelitefeather.cygnus.setup.util.SetupTags; import java.time.Duration; import java.time.temporal.ChronoUnit; @@ -20,10 +21,16 @@ public InstanceAddListener(UUID mainInstanceID) { @Override public void accept(AddEntityToInstanceEvent event) { - if (!(event.getEntity() instanceof Player)) return; + if (!(event.getEntity() instanceof Player player)) return; if (event.getInstance().getUuid().equals(mainInstanceID)) return; - MinecraftServer.getSchedulerManager().buildTask(() -> SetupItems.setSaveData((Player) event.getEntity())) - .delay(Duration.of(3, ChronoUnit.SECONDS)) - .schedule(); + + MinecraftServer.getSchedulerManager().scheduleNextTick(() -> { + int modeId = player.getTag(SetupTags.SETUP_ID_TAG).byteValue(); + if (modeId == 0) { + SetupItems.setLobbyLayout(player); + return; + } + SetupItems.setGameLayout(player); + }); } } From 89602961ca2f39e221ec3277b6662ad48ea89260 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 16:29:38 +0200 Subject: [PATCH 14/18] feat(setup): add mode enumeration --- .../setup/inventory/view/InventoryMode.java | 60 +++++++++++++++++++ .../inventory/view/InventoryModeTest.java | 47 +++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryMode.java create mode 100644 setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryModeTest.java diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryMode.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryMode.java new file mode 100644 index 00000000..5c9c6f7d --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryMode.java @@ -0,0 +1,60 @@ +package net.onelitefeather.cygnus.setup.inventory.view; + +import net.onelitefeather.cygnus.setup.map.MapDataCategory; + +import java.util.Arrays; +import java.util.EnumSet; +import java.util.Set; + + +/** + * Defines the available inventory modes for the {@link MapDataOverviewInventory}. + * Each mode specifies which {@link MapDataCategory} entries are displayed and at which slot positions. + * + *

The slot indices and categories are aligned by position — the first category maps to the first slot index, and so on.

+ * + *
    + *
  • {@link #LOBBY} — displays name, author, and spawn; used for lobby map setup.
  • + *
  • {@link #GAME} — additionally displays the slender category; used for game map setup.
  • + *
+ * + * @author Joltra + * @version 1.0.0 + * @since 2.5.0 + */ +public enum InventoryMode { + LOBBY(new int[]{11, 13, 15}, MapDataCategory.NAME, MapDataCategory.AUTHOR, MapDataCategory.SPAWN), + GAME(new int[]{10, 12, 14, 16}, MapDataCategory.NAME, MapDataCategory.AUTHOR, MapDataCategory.SPAWN, MapDataCategory.SLENDER); + + private final EnumSet categories; + private final int[] slots; + + /** + * Creates a new entry for this enumeration + * + * @param slots of the entry + * @param categories of the entry + */ + InventoryMode(int[] slots, MapDataCategory... categories) { + this.categories = EnumSet.copyOf(Arrays.asList(categories)); + this.slots = slots; + } + + /** + * Returns the range of slots + * + * @return an array of slot indices corresponding to the categories in this mode + */ + public int[] getSlots() { + return slots; + } + + /** + * Returns the categories from the entry. + * + * @return a set of {@link MapDataCategory} values + */ + public Set getCategories() { + return categories; + } +} \ No newline at end of file diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryModeTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryModeTest.java new file mode 100644 index 00000000..6fbfe1d1 --- /dev/null +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/inventory/view/InventoryModeTest.java @@ -0,0 +1,47 @@ +package net.onelitefeather.cygnus.setup.inventory.view; + +import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import org.junit.jupiter.api.Test; +import java.util.Set; +import static org.junit.jupiter.api.Assertions.*; + +class InventoryModeTest { + + @Test + void lobbyHasCorrectSlots() { + assertArrayEquals(new int[]{11, 13, 15}, InventoryMode.LOBBY.getSlots()); + } + + @Test + void lobbyHasCorrectCategories() { + Set categories = InventoryMode.LOBBY.getCategories(); + assertEquals(3, categories.size()); + assertTrue(categories.contains(MapDataCategory.NAME)); + assertTrue(categories.contains(MapDataCategory.AUTHOR)); + assertTrue(categories.contains(MapDataCategory.SPAWN)); + assertFalse(categories.contains(MapDataCategory.SLENDER)); + } + + @Test + void gameHasCorrectSlots() { + assertArrayEquals(new int[]{10, 12, 14, 16}, InventoryMode.GAME.getSlots()); + } + + @Test + void gameHasCorrectCategories() { + Set categories = InventoryMode.GAME.getCategories(); + assertEquals(4, categories.size()); + assertTrue(categories.contains(MapDataCategory.NAME)); + assertTrue(categories.contains(MapDataCategory.AUTHOR)); + assertTrue(categories.contains(MapDataCategory.SPAWN)); + assertTrue(categories.contains(MapDataCategory.SLENDER)); + } + + @Test + void slotCountMatchesCategoryCount() { + for (InventoryMode mode : InventoryMode.values()) { + assertEquals(mode.getSlots().length, mode.getCategories().size(), + "Slot count and category count must match for mode: " + mode.name()); + } + } +} \ No newline at end of file From b01a443f8aa1930e0b3d7378617aa9920ff07781 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 16:29:58 +0200 Subject: [PATCH 15/18] chore(setup): update constructor usage --- .../cygnus/setup/data/GameData.java | 7 ++--- .../cygnus/setup/data/LobbyData.java | 5 ++-- ...ory.java => MapDataOverviewInventory.java} | 26 +++++++++++-------- 3 files changed, 22 insertions(+), 16 deletions(-) rename setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/{GeneralMapOverviewInventory.java => MapDataOverviewInventory.java} (68%) 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 3fe4ea22..b7fa50a8 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 @@ -8,7 +8,8 @@ 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.view.MapDataOveriewInventory; +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.SetupItems; import net.onelitefeather.cygnus.setup.util.SetupMessages; @@ -21,7 +22,7 @@ public class GameData extends InstanceSetupData { - private final MapDataOveriewInventory inventory; + private final MapDataOverviewInventory inventory; private final SurvivorViewInventory survivorInventory; private GameMapBuilder gameMapBuilder; private boolean pageMode; @@ -41,7 +42,7 @@ public GameData(UUID uuid, MapEntry mapEntry) { } System.out.println("After loadData: " + System.identityHashCode(this.gameMapBuilder)); - this.inventory = new MapDataOveriewInventory(player, this.gameMapBuilder); + this.inventory = new MapDataOverviewInventory(player, this.gameMapBuilder, InventoryMode.GAME); this.survivorInventory = new SurvivorViewInventory(player, this.gameMapBuilder); } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java index 5b051498..4a6d6cf3 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java @@ -6,7 +6,8 @@ import net.minestom.server.entity.Player; import net.minestom.server.instance.anvil.AnvilLoader; import net.onelitefeather.cygnus.common.util.GsonHelper; -import net.onelitefeather.cygnus.setup.inventory.view.MapDataOveriewInventory; +import net.onelitefeather.cygnus.setup.inventory.view.InventoryMode; +import net.onelitefeather.cygnus.setup.inventory.view.MapDataOverviewInventory; import net.theevilreaper.aves.inventory.PersonalInventoryBuilder; import net.theevilreaper.aves.map.BaseMap; import net.theevilreaper.aves.map.BaseMapBuilder; @@ -30,7 +31,7 @@ public LobbyData(UUID uuid, MapEntry mapEntry) { throw new IllegalArgumentException("Player with UUID " + uuid + " is not online."); } - this.viewInventory = new MapDataOveriewInventory(player, this.mapBuilder); + this.viewInventory = new MapDataOverviewInventory(player, this.mapBuilder, InventoryMode.LOBBY); } @Override diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/GeneralMapOverviewInventory.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/MapDataOverviewInventory.java similarity index 68% rename from setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/GeneralMapOverviewInventory.java rename to setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/MapDataOverviewInventory.java index 906a6f9d..fcbafd09 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/GeneralMapOverviewInventory.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/MapDataOverviewInventory.java @@ -3,6 +3,7 @@ import net.kyori.adventure.text.Component; import net.minestom.server.entity.Player; import net.minestom.server.inventory.InventoryType; +import net.onelitefeather.cygnus.common.map.GameMapBuilder; import net.onelitefeather.cygnus.setup.inventory.slot.MultiStringSlot; import net.onelitefeather.cygnus.setup.inventory.slot.PositionSlot; import net.onelitefeather.cygnus.setup.inventory.slot.StringSlot; @@ -14,15 +15,16 @@ import net.theevilreaper.aves.inventory.util.LayoutCalculator; import net.theevilreaper.aves.map.BaseMapBuilder; -public class GeneralMapOverviewInventory extends PersonalInventoryBuilder { +import java.util.Iterator; +import java.util.Set; + +public class MapDataOverviewInventory extends PersonalInventoryBuilder { - private static final int[] DATA_SLOT = LayoutCalculator.from(10, 12, 14); private final BaseMapBuilder mapBuilder; - public GeneralMapOverviewInventory(Player player, BaseMapBuilder builder) { + public MapDataOverviewInventory(Player player, BaseMapBuilder builder, InventoryMode mode) { super(Component.text("Lobby data"), InventoryType.CHEST_3_ROW, player); this.mapBuilder = builder; - InventoryLayout backGround = InventoryLayout.fromType(getType()); backGround.setItems(LayoutCalculator.quad(0, getType().getSize() - 1), SetupItems.DECORATION_PANE); @@ -31,16 +33,17 @@ public GeneralMapOverviewInventory(Player player, BaseMapBuilder builder) { this.setDataLayoutFunction(dataLayoutFunction -> { InventoryLayout dataLayout = dataLayoutFunction == null ? InventoryLayout.fromType(getType()) : dataLayoutFunction; - dataLayout.blank(DATA_SLOT); - - MapDataCategory[] categories = MapDataCategory.getValues(); - for (int i = 0; i < categories.length && i < DATA_SLOT.length; i++) { - MapDataCategory currentType = categories[i]; - dataLayout.setItem(DATA_SLOT[i], getDataSlot(currentType)); + int[] slots = mode.getSlots(); + Set categories = mode.getCategories(); + Iterator iterator = categories.iterator(); + for (int i = 0; i < slots.length && iterator.hasNext(); i++) { + MapDataCategory category = iterator.next(); + dataLayout.setItem(slots[i], getDataSlot(category)); } return dataLayout; }); + this.invalidateLayout(); register(); } @@ -53,9 +56,10 @@ public GeneralMapOverviewInventory(Player player, BaseMapBuilder builder) { */ private ISlot getDataSlot(MapDataCategory category) { return switch (category) { - case NAME -> new StringSlot(MapDataCategory.NAME, mapBuilder.getName()); + case NAME -> new StringSlot(MapDataCategory.NAME, mapBuilder.getName()); case AUTHOR -> new MultiStringSlot(MapDataCategory.AUTHOR, mapBuilder.getBuilders()); case SPAWN -> new PositionSlot(MapDataCategory.SPAWN, mapBuilder.getSpawn()); + case SLENDER -> new PositionSlot(MapDataCategory.SLENDER, ((GameMapBuilder) mapBuilder).getSlenderSpawn()); default -> throw new IllegalStateException("Unknown category: " + category); }; } From 385a88570b7c1bd18696de310d548d45176c6c73 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 16:30:15 +0200 Subject: [PATCH 16/18] chore(setup): add new update trigger call --- .../cygnus/setup/listener/position/PositionSetListener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java index 5eb7d11d..02be5edb 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java @@ -42,6 +42,7 @@ public void accept(PositionSetEvent event) { } case SLENDER -> { ((GameMapBuilder) gameData.getMapBuilder()).setSlenderSpawn(event.getPos()); + gameData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); } default -> { // Nothing to do here From cbdef6e75792f5d23a748ee7cb443f389df25f64 Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 16:30:41 +0200 Subject: [PATCH 17/18] chore(setup): add new listener --- .../cygnus/setup/SetupExtension.java | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java index eca6104b..f4423491 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java @@ -8,6 +8,7 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.event.player.PlayerBlockBreakEvent; import net.minestom.server.event.player.PlayerCustomClickEvent; +import net.minestom.server.event.player.PlayerDisconnectEvent; import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.event.player.PlayerUseItemEvent; import net.onelitefeather.cygnus.common.ListenerHandling; @@ -15,6 +16,7 @@ import net.onelitefeather.cygnus.setup.command.SetupCommand; import net.onelitefeather.cygnus.setup.event.MapSetupSaveEvent; import net.onelitefeather.cygnus.setup.event.MapSetupSelectEvent; +import net.onelitefeather.cygnus.setup.event.PositionSetEvent; import net.onelitefeather.cygnus.setup.event.dialog.DialogRequestEvent; import net.onelitefeather.cygnus.setup.inventory.MapSetupInventory; import net.onelitefeather.cygnus.setup.listener.InstanceAddListener; @@ -26,8 +28,8 @@ import net.onelitefeather.cygnus.setup.listener.dialog.DialogPayloadListener; import net.onelitefeather.cygnus.setup.listener.dialog.DialogRequestListener; import net.onelitefeather.cygnus.setup.listener.map.MapSetupSaveListener; +import net.onelitefeather.cygnus.setup.listener.position.PositionSetListener; import net.onelitefeather.cygnus.setup.map.SetupMapProvider; -import net.onelitefeather.cygnus.setup.util.SetupData; import net.theevilreaper.aves.map.provider.AbstractMapProvider; import net.theevilreaper.aves.util.functional.PlayerConsumer; import net.onelitefeather.guira.SetupDataService; @@ -39,14 +41,12 @@ public class SetupExtension implements ListenerHandling { private final SetupDataService dataService; - private final SetupData setupData; private final MapSetupInventory mapSetupInventory; private final AbstractMapProvider mapProvider; public SetupExtension() { - this.setupData = new SetupData(); this.dataService = SetupDataService.create(); - this.mapProvider = new SetupMapProvider(Paths.get("")); + this.mapProvider = new SetupMapProvider(Paths.get("").resolve("setup")); this.mapSetupInventory = new MapSetupInventory(mapProvider.getEntries()); registerSetupComponents(); this.registerMapListeners(); @@ -61,13 +61,16 @@ private void registerSetupComponents() { Supplier instanceSupplier = this.mapProvider.getActiveInstance(); UUID instanceUUID = instanceSupplier.get().getUuid(); - manager.addListener(MapSetupSelectEvent.class, new MapSetupSelectListener(setupData)); - manager.addListener(PlayerUseItemEvent.class, new SetupItemListener(setupData, mapSetupInventory)); + manager.addListener(MapSetupSelectEvent.class, new MapSetupSelectListener(this.dataService)); + manager.addListener(PlayerUseItemEvent.class, new SetupItemListener(this.dataService, mapSetupInventory)); manager.addListener(AsyncPlayerConfigurationEvent.class, event -> event.setSpawningInstance(instanceSupplier.get())); manager.addListener(PlayerSpawnEvent.class, new PlayerSpawnListener(spawnPos)); - manager.addListener(PlayerBlockBreakEvent.class, new PageCreationListener(setupData)); + manager.addListener(PlayerDisconnectEvent.class, event -> { + this.dataService.remove(event.getPlayer().getUuid()); + }); + manager.addListener(PlayerBlockBreakEvent.class, new PageCreationListener(this.dataService)); manager.addListener(AddEntityToInstanceEvent.class, new InstanceAddListener(instanceUUID)); manager.addListener(RemoveEntityFromInstanceEvent.class, new InstanceRemoveListener(instanceUUID)); @@ -75,7 +78,9 @@ private void registerSetupComponents() { //Dialog listener manager.addListener(DialogRequestEvent.class, new DialogRequestListener()); - manager.addListener(PlayerCustomClickEvent.class, new DialogPayloadListener(setupData)); + manager.addListener(PlayerCustomClickEvent.class, new DialogPayloadListener(this.dataService)); + + manager.addListener(PositionSetEvent.class, new PositionSetListener(this.dataService)); } /** @@ -84,6 +89,6 @@ private void registerSetupComponents() { private void registerMapListeners() { GlobalEventHandler node = MinecraftServer.getGlobalEventHandler(); PlayerConsumer teleport = player -> this.mapProvider.teleportToSpawn(player, true); - node.addListener(MapSetupSaveEvent.class, new MapSetupSaveListener(teleport)); + node.addListener(MapSetupSaveEvent.class, new MapSetupSaveListener(this.dataService, teleport)); } } From dcd542a05db004c55a19586fc13a85b91181876b Mon Sep 17 00:00:00 2001 From: Joltras Date: Sun, 28 Jun 2026 16:37:31 +0200 Subject: [PATCH 18/18] chore(setup): improve position set logic --- .../cygnus/setup/data/GameData.java | 23 +++++++++++ .../cygnus/setup/data/InstanceSetupData.java | 20 ++++++++- .../cygnus/setup/data/LobbyData.java | 30 ++++++++++++++ .../position/PositionSetListener.java | 41 +------------------ 4 files changed, 74 insertions(+), 40 deletions(-) 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 b7fa50a8..1ea04658 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 @@ -12,6 +12,7 @@ import net.onelitefeather.cygnus.setup.inventory.view.MapDataOverviewInventory; import net.onelitefeather.cygnus.setup.inventory.view.SurvivorViewInventory; import net.onelitefeather.cygnus.setup.item.SetupItems; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.onelitefeather.cygnus.setup.util.SetupMessages; import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; @@ -81,6 +82,28 @@ public void triggerUpdate(InventoryTarget target) { } } + /** + * {@inheritDoc} + */ + @Override + public void setPosition(MapDataCategory category, Player player) { + Pos pos = player.getPosition(); + switch (category) { + case SPAWN -> { + getMapBuilder().spawn(pos); + triggerUpdate(InventoryTarget.GENERAL); + } + case SLENDER -> { + ((GameMapBuilder) getMapBuilder()).setSlenderSpawn(pos); + triggerUpdate(InventoryTarget.GENERAL); + } + default -> {} + } + } + + /** + * {@inheritDoc} + */ @Override public void handleItemInteraction(Player player, byte tagValue) { if (3 == tagValue) { diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java index 2ea14de0..08429135 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/InstanceSetupData.java @@ -7,6 +7,7 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.InstanceContainer; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.onelitefeather.guira.data.SetupData; import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; @@ -22,7 +23,7 @@ * setup-specific interaction and update logic.

* * @author theEvilReaper - * @version 1.0.0 + * @version 2.0.0 * @since 2.1.0 */ public abstract class InstanceSetupData implements SetupData { @@ -80,6 +81,23 @@ public void teleport(Player player) { */ public abstract void triggerUpdate(InventoryTarget target); + /** + * Handles the position change of a player during the setup. + * + * @param category the category of the map data being modified + * @param player who is involved in the position change + */ + public abstract void setPosition(MapDataCategory category, Player player); + + /** + * Handles an item interaction by the given player during the setup process. + * The default implementation opens the general inventory. + * Subclasses may override this to handle additional tag values. + * + * @param player the player who interacted with the item + * @param tagValue the tag value of the used item + * @see GameData#handleItemInteraction(Player, byte) + */ public void handleItemInteraction(Player player, byte tagValue) { openInventory(InventoryTarget.GENERAL); } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java index 4a6d6cf3..991b3979 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/LobbyData.java @@ -8,6 +8,7 @@ import net.onelitefeather.cygnus.common.util.GsonHelper; import net.onelitefeather.cygnus.setup.inventory.view.InventoryMode; import net.onelitefeather.cygnus.setup.inventory.view.MapDataOverviewInventory; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.theevilreaper.aves.inventory.PersonalInventoryBuilder; import net.theevilreaper.aves.map.BaseMap; import net.theevilreaper.aves.map.BaseMapBuilder; @@ -34,16 +35,36 @@ public LobbyData(UUID uuid, MapEntry mapEntry) { this.viewInventory = new MapDataOverviewInventory(player, this.mapBuilder, InventoryMode.LOBBY); } + /** + * {@inheritDoc} + */ + @Override + public void setPosition(MapDataCategory category, Player player) { + if (category == MapDataCategory.SPAWN) { + getMapBuilder().spawn(player.getPosition()); + triggerUpdate(InventoryTarget.GENERAL); + } + } + + /** + * {@inheritDoc} + */ @Override public void openInventory(InventoryTarget target) { this.viewInventory.open(); } + /** + * {@inheritDoc} + */ @Override public void triggerUpdate(InventoryTarget target) { this.viewInventory.invalidateDataLayout(); } + /** + * {@inheritDoc} + */ @Override public void save() { if (!Files.exists(mapEntry.getMapFile())) { @@ -52,6 +73,9 @@ public void save() { GsonHelper.FILE_HANDLER.save(mapEntry.getMapFile(), BaseMap.class); } + /** + * {@inheritDoc} + */ @Override public void teleport(Player player) { super.teleport(player); @@ -61,12 +85,18 @@ public void teleport(Player player) { player.setInstance(this.instance, spawnPoint); } + /** + * {@inheritDoc} + */ @Override public void reset() { super.reset(); this.viewInventory.unregister(); } + /** + * {@inheritDoc} + */ @Override public void loadData() { if (this.mapEntry == null) { diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java index 02be5edb..d0b7652c 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/position/PositionSetListener.java @@ -1,15 +1,9 @@ package net.onelitefeather.cygnus.setup.listener.position; -import net.onelitefeather.cygnus.common.map.GameMapBuilder; -import net.onelitefeather.cygnus.setup.data.GameData; import net.onelitefeather.cygnus.setup.data.InstanceSetupData; -import net.onelitefeather.cygnus.setup.data.LobbyData; import net.onelitefeather.cygnus.setup.event.PositionSetEvent; -import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.onelitefeather.guira.SetupDataService; -import net.onelitefeather.guira.data.SetupData; -import java.util.Optional; import java.util.function.Consumer; public class PositionSetListener implements Consumer { @@ -22,38 +16,7 @@ public PositionSetListener(SetupDataService dataService) { @Override public void accept(PositionSetEvent event) { - MapDataCategory category = event.getCategory(); - - Optional optionalSetupData = this.dataService.get(event.getPlayer().getUuid()); - - if (optionalSetupData.isEmpty()) return; - - switch (optionalSetupData.get()) { - case LobbyData lobbyData -> { - lobbyData.getMapBuilder().spawn(event.getPos()); - lobbyData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); - } - case GameData gameData -> { - switch (category) { - case SPAWN -> { - gameData.getMapBuilder().spawn(event.getPos()); - gameData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); - - } - case SLENDER -> { - ((GameMapBuilder) gameData.getMapBuilder()).setSlenderSpawn(event.getPos()); - gameData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); - } - default -> { - // Nothing to do here - } - } - } - default -> { - // Nothing to do here - } - } - - + this.dataService.get(event.getPlayer().getUuid()).ifPresent(data -> + ((InstanceSetupData) data).setPosition(event.getCategory(), event.getPlayer())); } }