diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/TamiasSetup.java b/setup/src/main/java/net/theevilreaper/tamias/setup/TamiasSetup.java index 1793312b..5193c328 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/TamiasSetup.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/TamiasSetup.java @@ -1,9 +1,8 @@ package net.theevilreaper.tamias.setup; +import net.minestom.server.event.player.PlayerCustomClickEvent; import net.onelitefeather.guira.SetupDataService; import net.onelitefeather.guira.event.SetupFinishEvent; -import net.theevilreaper.aves.file.FileHandler; -import net.theevilreaper.aves.file.GsonFileHandler; import net.theevilreaper.aves.map.provider.MapProvider; import net.theevilreaper.aves.util.functional.PlayerConsumer; import net.minestom.server.MinecraftServer; @@ -17,16 +16,21 @@ import net.minestom.server.event.player.PlayerSpawnEvent; import net.minestom.server.event.player.PlayerUseItemEvent; import net.minestom.server.instance.Instance; -import net.minestom.server.tag.Tag; import net.theevilreaper.tamias.common.ListenerHandling; -import net.theevilreaper.tamias.common.gson.GsonUtil; import net.theevilreaper.tamias.setup.commands.SetupCommand; +import net.theevilreaper.tamias.setup.dialog.DialogRegistry; +import net.theevilreaper.tamias.setup.dialog.SetupDialogRegistry; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDeletePromptEvent; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent; import net.theevilreaper.tamias.setup.event.MapSetupSelectEvent; import net.theevilreaper.tamias.setup.inventory.MapSetupInventory; import net.theevilreaper.tamias.setup.listener.PlayerChatListener; import net.theevilreaper.tamias.setup.listener.PlayerConfigurationListener; import net.theevilreaper.tamias.setup.listener.PlayerDisconnectListener; import net.theevilreaper.tamias.setup.listener.PlayerSpawnListener; +import net.theevilreaper.tamias.setup.listener.dialog.PlayerCustomClickEventListener; +import net.theevilreaper.tamias.setup.listener.dialog.PlayerDeletePromptListener; +import net.theevilreaper.tamias.setup.listener.dialog.PlayerDialogRequestListener; import net.theevilreaper.tamias.setup.listener.item.PlayerUseItemListener; import net.theevilreaper.tamias.setup.listener.entity.EntityAddToInstanceListener; import net.theevilreaper.tamias.setup.listener.map.SetupFinishListener; @@ -40,21 +44,18 @@ public final class TamiasSetup implements ListenerHandling { - public static final Tag SETUP_TAG = Tag.Transient("setup"); - public static final Tag DELETE_TAG = Tag.Boolean("delete").defaultValue(false); - private final SetupDataService setupDataService; - private final FileHandler fileHandler; private final MapProvider mapProvider; private final SetupItems setupItems; private final MapSetupInventory mapSetupInventory; + private final DialogRegistry dialogRegistry; public TamiasSetup() { - this.fileHandler = new GsonFileHandler(GsonUtil.GSON); - this.mapProvider = new SetupMapProvider(Paths.get(""), this.fileHandler); + this.mapProvider = new SetupMapProvider(Paths.get("")); this.setupDataService = SetupDataService.create(); this.setupItems = new SetupItems(); this.mapSetupInventory = new MapSetupInventory(this.mapProvider::getEntries); + this.dialogRegistry = new SetupDialogRegistry(); MinecraftServer.getSchedulerManager().buildShutdownTask(this::terminate); } @@ -69,7 +70,7 @@ public void terminate() { } private void registerListener() { - GlobalEventHandler manager = MinecraftServer.getGlobalEventHandler(); + GlobalEventHandler node = MinecraftServer.getGlobalEventHandler(); Supplier instanceSupplier = mapProvider.getActiveInstance(); SetupMapProvider setupMapProvider = (SetupMapProvider) mapProvider; PlayerConsumer initialSpawnSupplier = player -> { @@ -80,16 +81,22 @@ private void registerListener() { setupMapProvider.teleportToSpawn(player, true); setupItems.setOverViewItem(player); }; - manager.addListener(PlayerDisconnectEvent.class, new PlayerDisconnectListener(setupDataService::remove)); - manager.addListener(AsyncPlayerConfigurationEvent.class, new PlayerConfigurationListener(instanceSupplier)); - manager.addListener(PlayerSpawnEvent.class, new PlayerSpawnListener(initialSpawnSupplier)); - manager.addListener(AddEntityToInstanceEvent.class, new EntityAddToInstanceListener(instanceSupplier, setupItems)); - manager.addListener(MapSetupSelectEvent.class, new MapSetupSelectListener(this.fileHandler, this.setupDataService)); - manager.addListener(SetupFinishEvent.class, new SetupFinishListener(instanceSwitcher)); - manager.addListener(PlayerChatEvent.class, new PlayerChatListener(this.setupDataService)); + node.addListener(PlayerDisconnectEvent.class, new PlayerDisconnectListener(setupDataService::remove)); + node.addListener(AsyncPlayerConfigurationEvent.class, new PlayerConfigurationListener(instanceSupplier)); + node.addListener(PlayerSpawnEvent.class, new PlayerSpawnListener(initialSpawnSupplier)); + node.addListener(AddEntityToInstanceEvent.class, new EntityAddToInstanceListener(instanceSupplier, setupItems)); + node.addListener(MapSetupSelectEvent.class, new MapSetupSelectListener(this.setupDataService)); + node.addListener(SetupFinishEvent.class, new SetupFinishListener(instanceSwitcher)); + node.addListener(PlayerChatEvent.class, new PlayerChatListener(this.setupDataService)); // Item listener - manager.addListener(PlayerUseItemEvent.class, new PlayerUseItemListener(this::updateMapInventory, setupDataService::get)); + node.addListener(PlayerUseItemEvent.class, new PlayerUseItemListener(this::updateMapInventory, setupDataService::get)); + + //Dialogs + node.addListener(PlayerDeletePromptEvent.class, new PlayerDeletePromptListener(dialogRegistry)); + node.addListener(PlayerCustomClickEvent.class, new PlayerCustomClickEventListener(this.dialogRegistry, this.setupDataService::get)); + node.addListener(PlayerDialogRequestEvent.class, new PlayerDialogRequestListener(this.dialogRegistry)); + } /** diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/SetupCommand.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/SetupCommand.java index 92239b05..be75c6ee 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/SetupCommand.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/SetupCommand.java @@ -4,10 +4,7 @@ import net.minestom.server.command.builder.condition.Conditions; import net.onelitefeather.guira.SetupDataService; import net.theevilreaper.tamias.setup.commands.parts.SetupAreaCommand; -import net.theevilreaper.tamias.setup.commands.parts.SetupBuildersCommand; -import net.theevilreaper.tamias.setup.commands.parts.SetupNameCommand; import net.theevilreaper.tamias.setup.commands.parts.SetupPositionCommand; -import org.jetbrains.annotations.NotNull; /** * The {@link SetupCommand} is the main command for the setup process. @@ -19,11 +16,9 @@ */ public final class SetupCommand extends Command { - public SetupCommand(@NotNull SetupDataService dataService) { + public SetupCommand(SetupDataService dataService) { super("setup"); this.setCondition(Conditions::playerOnly); - this.addSubcommand(new SetupNameCommand(dataService::get)); - this.addSubcommand(new SetupBuildersCommand(dataService::get)); this.addSubcommand(new SetupPositionCommand(dataService::get)); this.addSubcommand(new SetupAreaCommand(dataService::get)); } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/package-info.java similarity index 56% rename from setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/package-info.java rename to setup/src/main/java/net/theevilreaper/tamias/setup/commands/package-info.java index fc3a9871..67891fa0 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/package-info.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/package-info.java @@ -1,4 +1,4 @@ @NotNullByDefault -package net.theevilreaper.tamias.setup.event.dialog; +package net.theevilreaper.tamias.setup.commands; import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupAreaCommand.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupAreaCommand.java index b631bfc2..98a94071 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupAreaCommand.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupAreaCommand.java @@ -14,11 +14,11 @@ import net.minestom.server.utils.Direction; import net.onelitefeather.guira.data.SetupData; import net.theevilreaper.aves.util.Components; +import net.theevilreaper.tamias.common.map.builder.GameMapBuilder; import net.theevilreaper.tamias.common.util.Messages; -import net.theevilreaper.tamias.setup.TamiasSetup; import net.theevilreaper.tamias.setup.data.GameData; import net.theevilreaper.tamias.setup.util.DirectionUtil; -import org.jetbrains.annotations.NotNull; +import net.theevilreaper.tamias.setup.util.SetupTags; import java.util.Optional; import java.util.UUID; @@ -36,7 +36,7 @@ public class SetupAreaCommand extends Command { private final Function> setupDataFunction; private final ArgumentWord argumentWord; - public SetupAreaCommand(@NotNull Function> setupDataFunction) { + public SetupAreaCommand(Function> setupDataFunction) { super("area"); this.setCondition(Conditions::playerOnly); this.setupDataFunction = setupDataFunction; @@ -48,8 +48,8 @@ public SetupAreaCommand(@NotNull Function> setupDataFu this.addSyntax(this::handleStateChange, stateChange); } - private void handleStateChange(@NotNull CommandSender sender, @NotNull CommandContext context) { - if (!sender.hasTag(TamiasSetup.SETUP_TAG)) { + private void handleStateChange(CommandSender sender, CommandContext context) { + if (!sender.hasTag(SetupTags.SETUP_TAG)) { sender.sendMessage(SELECT_MAP_FIRST); return; } @@ -71,8 +71,8 @@ private void handleStateChange(@NotNull CommandSender sender, @NotNull CommandCo } } - private void handlePositionSet(@NotNull CommandSender sender, @NotNull CommandContext context) { - if (!sender.hasTag(TamiasSetup.SETUP_TAG)) { + private void handlePositionSet(CommandSender sender, CommandContext context) { + if (!sender.hasTag(SetupTags.SETUP_TAG)) { sender.sendMessage(SELECT_MAP_FIRST); return; } @@ -107,15 +107,17 @@ private void handlePositionSet(@NotNull CommandSender sender, @NotNull CommandCo * @param player the player who executed the command * @param setupData the game data containing the map builder */ - private void setLeftCorner(@NotNull Player player, @NotNull GameData setupData) { + private void setLeftCorner(Player player, GameData setupData) { Optional directionOptional = DirectionUtil.parseDirection(player); if (directionOptional.isEmpty()) return; Vec vec = player.getPosition().asVec().sub(0, -1, 0); Direction direction = directionOptional.get(); - setupData.getGameMapBuilder().areaLowerCorner(vec); - setupData.getGameMapBuilder().areaFacing(direction); + GameMapBuilder mapBuilder = (GameMapBuilder) setupData.getMapBuilder(); + + mapBuilder.areaLowerCorner(vec); + mapBuilder.areaFacing(direction); Component component = Messages.withPrefix(Component.text("Left area corner is: ", NamedTextColor.GRAY) .append(Components.convertPoint(vec).style(Style.style(NamedTextColor.GOLD))) @@ -131,10 +133,12 @@ private void setLeftCorner(@NotNull Player player, @NotNull GameData setupData) * @param player the player who executed the command * @param setupData the game data containing the map builder */ - private void setRightCorner(@NotNull Player player, @NotNull GameData setupData) { + private void setRightCorner(Player player, GameData setupData) { Vec vec = player.getPosition().asVec(); - setupData.getGameMapBuilder().areaUpperCorner(vec); + GameMapBuilder mapBuilder = (GameMapBuilder) setupData.getMapBuilder(); + + mapBuilder.areaUpperCorner(vec); Component component = Messages.withPrefix(Component.text("Right area corner is: ", NamedTextColor.GRAY) .append(Components.convertPoint(vec).style(Style.style(NamedTextColor.GOLD)))); player.sendMessage(component); diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupBuildersCommand.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupBuildersCommand.java deleted file mode 100644 index cf0a141a..00000000 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupBuildersCommand.java +++ /dev/null @@ -1,73 +0,0 @@ -package net.theevilreaper.tamias.setup.commands.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.CommandSender; -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.CommandContext; -import net.minestom.server.command.builder.arguments.ArgumentStringArray; -import net.minestom.server.command.builder.arguments.ArgumentType; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.guira.data.SetupData; -import net.theevilreaper.aves.map.BaseMap; -import net.theevilreaper.tamias.setup.TamiasSetup; -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.function.Function; - -import static net.theevilreaper.tamias.setup.util.SetupMessages.SELECT_MAP_FIRST; - -/** - * The command allows the set the creators of a map to a {@link BaseMap} reference. - * - * @author theEvilReaper - * @version 1.0.0 - * @since 1.0.0 - */ -public final class SetupBuildersCommand extends Command { - - private final Function> setupDataFunction; - - public SetupBuildersCommand(@NotNull Function> setupDataFunction) { - super("builders"); - this.setupDataFunction = setupDataFunction; - this.setCondition(Conditions::playerOnly); - - ArgumentStringArray buildersArray = ArgumentType.StringArray("builders"); - this.addSyntax(this::handleBuilderSetup, buildersArray); - } - - private void handleBuilderSetup(@NotNull CommandSender sender, @NotNull CommandContext context) { - if (!sender.hasTag(TamiasSetup.SETUP_TAG)) { - sender.sendMessage(SELECT_MAP_FIRST); - return; - } - - String[] builders = context.get("builders"); - - if (builders.length == 0) { - sender.sendMessage(Component.text("A map needs at least one builder", NamedTextColor.RED)); - return; - } - - Optional setupData = this.setupDataFunction.apply(sender.identity().uuid()); - if (setupData.isEmpty()) { - sender.sendMessage(SELECT_MAP_FIRST); - return; - } - - // setupData.get().getMap().get().setBuilders(builders); - Component buildersAsComponent = Component.join(JoinConfiguration.arrayLike(), transformBuilders(builders)); - sender.sendMessage(Component.text("The creators of the map are: ").append(buildersAsComponent)); - } - - private @NotNull List transformBuilders(@NotNull String... builders) { - return Arrays.stream(builders).map(Component::text).toList(); - } -} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupNameCommand.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupNameCommand.java deleted file mode 100644 index 54d38a06..00000000 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupNameCommand.java +++ /dev/null @@ -1,64 +0,0 @@ -package net.theevilreaper.tamias.setup.commands.parts; - -import net.minestom.server.command.CommandSender; -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.CommandContext; -import net.minestom.server.command.builder.arguments.ArgumentString; -import net.minestom.server.command.builder.arguments.ArgumentType; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.guira.data.SetupData; -import net.theevilreaper.tamias.setup.TamiasSetup; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; -import java.util.UUID; -import java.util.function.Function; - -import static net.theevilreaper.tamias.setup.util.SetupMessages.SELECT_MAP_FIRST; - -public final class SetupNameCommand extends Command { - - private final Function> setupDataFunction; - - public SetupNameCommand(@NotNull Function> setupDataFunction) { - super("name"); - this.setupDataFunction = setupDataFunction; - this.setCondition(Conditions::playerOnly); - ArgumentString mapName = ArgumentType.String("mapName"); - this.addSyntax(this::handleNameSet, mapName); - } - - private void handleNameSet(@NotNull CommandSender sender, @NotNull CommandContext context) { - if (!sender.hasTag(TamiasSetup.SETUP_TAG)) { - sender.sendMessage(SELECT_MAP_FIRST); - return; - } - - String name = context.get("mapName"); - if (name == null || name.trim().isEmpty()) { - sender.sendMessage("Please provide a valid name"); - return; - } - - Optional setupData = this.setupDataFunction.apply(sender.identity().uuid()); - if (setupData.isEmpty()) { - sender.sendMessage(SELECT_MAP_FIRST); - return; - } - - SetupData data = setupData.get(); - - /*if (data.getMap().isEmpty()) { - sender.sendMessage("No map is currently selected. Please select a map first."); - return; - } - - BaseMap baseMap = data.getMap().get(); - - baseMap.setName(name); - Component message = Messages.withPrefix(Component.text("The name of the map now is: ", NamedTextColor.GRAY)) - .append(Component.text(name, NamedTextColor.AQUA)); - sender.sendMessage(message); - data.triggerUpdate();*/ - } -} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupPositionCommand.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupPositionCommand.java index 30d5c50b..6f9eadd0 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupPositionCommand.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/SetupPositionCommand.java @@ -18,13 +18,11 @@ import net.theevilreaper.aves.util.Components; import net.theevilreaper.tamias.common.map.builder.GameMapBuilder; import net.theevilreaper.tamias.common.util.Messages; -import net.theevilreaper.tamias.setup.TamiasSetup; import net.theevilreaper.tamias.setup.commands.type.SpawnType; -import net.theevilreaper.tamias.setup.data.GameData; import net.theevilreaper.tamias.setup.data.InstanceSetupData; import net.theevilreaper.tamias.setup.data.LobbyData; import net.theevilreaper.tamias.setup.util.DirectionUtil; -import org.jetbrains.annotations.NotNull; +import net.theevilreaper.tamias.setup.util.SetupTags; import java.util.Optional; @@ -34,7 +32,7 @@ public final class SetupPositionCommand extends Command { private final OptionalSetupDataGetter setupDataFunction; - public SetupPositionCommand(@NotNull OptionalSetupDataGetter setupDataFunction) { + public SetupPositionCommand(OptionalSetupDataGetter setupDataFunction) { super("position"); this.setCondition(Conditions::playerOnly); this.setupDataFunction = setupDataFunction; @@ -43,8 +41,8 @@ public SetupPositionCommand(@NotNull OptionalSetupDataGetter setupDataFunction) this.addSyntax(this::handleSpawnSet, spawnType); } - private void handleSpawnSet(@NotNull CommandSender sender, @NotNull CommandContext context) { - if (!sender.hasTag(TamiasSetup.SETUP_TAG)) { + private void handleSpawnSet(CommandSender sender, CommandContext context) { + if (!sender.hasTag(SetupTags.SETUP_TAG)) { sender.sendMessage(SELECT_MAP_FIRST); return; } @@ -70,7 +68,7 @@ private void handleSpawnSet(@NotNull CommandSender sender, @NotNull CommandConte if (data instanceof LobbyData lobbyData) { this.handleLobbySpawnSet(player, lobbyData.getMapBuilder(), spawnType); } else { - this.handleGameSpawnSet(player, ((GameData)data).getGameMapBuilder(), spawnType); + this.handleGameSpawnSet(player, ((InstanceSetupData)data).getMapBuilder(), spawnType); } Component posAsComponent = Components.convertPoint(player.getPosition()); Component argComponent = Component.text(type, NamedTextColor.GREEN); @@ -91,11 +89,11 @@ private void handleSpawnSet(@NotNull CommandSender sender, @NotNull CommandConte * @param builder the map builder to set the spawn * @param spawnType the type of spawn to set */ - private void handleGameSpawnSet(@NotNull Player sender, @NotNull GameMapBuilder builder, @NotNull SpawnType spawnType) { + private void handleGameSpawnSet(Player sender, BaseMapBuilder builder, SpawnType spawnType) { Pos position = sender.getPosition(); switch (spawnType) { case MAP_SPAWN, SPECTATOR -> builder.spawn(position); - case BOMBER -> builder.bomberSpawn(position); + case BOMBER -> ((GameMapBuilder)builder).bomberSpawn(position); case SURVIVOR -> this.handleSurvivorSpawnSet(sender, builder); } } @@ -106,16 +104,17 @@ private void handleGameSpawnSet(@NotNull Player sender, @NotNull GameMapBuilder * @param player the player who executed the command * @param builder the map builder to set the spawn */ - private void handleSurvivorSpawnSet(@NotNull Player player, @NotNull GameMapBuilder builder) { + private void handleSurvivorSpawnSet(Player player, BaseMapBuilder builder) { Optional determinedDirection = DirectionUtil.parseDirection(player); if (determinedDirection.isEmpty()) return; Pos pos = player.getPosition(); Direction direction = determinedDirection.get(); + GameMapBuilder gameMapBuilder = (GameMapBuilder) builder; - builder.spawnLayerDirection(direction); - builder.spawnLayerPos(pos); + gameMapBuilder.spawnLayerDirection(direction); + gameMapBuilder.spawnLayerPos(pos); Component component = Messages.withPrefix(Component.text("Created round spawn at: ", NamedTextColor.GRAY) .append(Components.convertPoint(pos).style(Style.style(NamedTextColor.GOLD))) @@ -131,7 +130,7 @@ private void handleSurvivorSpawnSet(@NotNull Player player, @NotNull GameMapBuil * @param builder the map builder to set the spawn * @param spawnType the type of spawn to set */ - private void handleLobbySpawnSet(@NotNull Player sender, @NotNull BaseMapBuilder builder, @NotNull SpawnType spawnType) { + private void handleLobbySpawnSet(Player sender, BaseMapBuilder builder, SpawnType spawnType) { if (spawnType != SpawnType.MAP_SPAWN) { sender.sendMessage("A lobby map can only have a spawn"); return; diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/package-info.java new file mode 100644 index 00000000..bbd4eb3f --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/parts/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.commands.parts; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/SpawnType.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/SpawnType.java index 67c28b9c..70a4ce8e 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/SpawnType.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/SpawnType.java @@ -1,6 +1,5 @@ package net.theevilreaper.tamias.setup.commands.type; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public enum SpawnType { @@ -13,15 +12,15 @@ public enum SpawnType { private static final SpawnType[] VALUES = values(); private final String displayName; - SpawnType(@NotNull String displayName) { + SpawnType(String displayName) { this.displayName = displayName; } - public @NotNull String getDisplayName() { + public String getDisplayName() { return displayName; } - public static @Nullable SpawnType fromString(@NotNull String name) { + public static @Nullable SpawnType fromString(String name) { SpawnType type = null; for (int i = 0; i < VALUES.length && type == null; i++) { SpawnType current = VALUES[i]; @@ -32,7 +31,7 @@ public enum SpawnType { return type; } - public static @NotNull String[] getAsArray() { + public static String[] getAsArray() { String[] array = new String[VALUES.length]; for (int i = 0; i < VALUES.length; i++) { array[i] = VALUES[i].getDisplayName(); diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/package-info.java new file mode 100644 index 00000000..91bd296e --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/commands/type/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.commands.type; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/data/GameData.java b/setup/src/main/java/net/theevilreaper/tamias/setup/data/GameData.java index 989df6af..bb2b2a41 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/data/GameData.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/data/GameData.java @@ -2,10 +2,11 @@ import net.kyori.adventure.bossbar.BossBar; import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.anvil.AnvilLoader; -import net.theevilreaper.aves.file.FileHandler; import net.theevilreaper.aves.map.BaseMap; +import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; import net.theevilreaper.tamias.common.map.GameMap; import net.theevilreaper.tamias.common.map.builder.GameMapBuilder; @@ -16,9 +17,10 @@ import java.util.Optional; import java.util.UUID; +import static net.theevilreaper.tamias.setup.map.SetupMapProvider.FILE_HANDLER; + public class GameData extends InstanceSetupData { - private final FileHandler fileHandler; private LobbyViewInventory inventory; private GameMapBuilder gameMapBuilder; private boolean areaMode; @@ -28,13 +30,11 @@ public class GameData extends InstanceSetupData { * * @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(@NotNull UUID uuid, @NotNull MapEntry mapEntry, @NotNull FileHandler fileHandler) { + public GameData(@NotNull UUID uuid, @NotNull 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."); } @@ -71,7 +71,16 @@ public void save() { if (!Files.exists(mapEntry.getMapFile())) { this.mapEntry.createFile(); } - this.fileHandler.save(mapEntry.getMapFile(), BaseMap.class); + FILE_HANDLER.save(mapEntry.getMapFile(), BaseMap.class); + } + + @Override + public void teleport(@NotNull Player player) { + super.teleport(player); + Pos spawnPoint = this.gameMapBuilder.getSpawn() == null + ? SPAWN_POINT + : this.gameMapBuilder.getSpawn(); + player.setInstance(this.instance, spawnPoint); } /** @@ -88,14 +97,16 @@ public void reset() { */ @Override public void loadData() { - if (this.mapEntry != null) return; - Optional mapData = fileHandler.load(mapEntry.getMapFile(), GameMap.class); - mapData.ifPresentOrElse(gameMap -> - this.gameMapBuilder = new GameMapBuilder(gameMap), - () -> this.gameMapBuilder = new GameMapBuilder() - ); + if (this.mapEntry == null || !this.mapEntry.hasMapFile()) { + this.gameMapBuilder = new GameMapBuilder(); + } else { + Optional mapData = FILE_HANDLER.load(mapEntry.getMapFile(), GameMap.class); + mapData.ifPresentOrElse(gameMap -> + this.gameMapBuilder = new GameMapBuilder(gameMap), + () -> this.gameMapBuilder = new GameMapBuilder() + ); + } this.inventory = new LobbyViewInventory(this.gameMapBuilder); - this.instance = MinecraftServer.getInstanceManager().createInstanceContainer(); AnvilLoader anvilLoader = new AnvilLoader(this.mapEntry.getDirectoryRoot()); this.instance.setChunkLoader(anvilLoader); @@ -117,7 +128,8 @@ public boolean hasAreaMode() { * * @return the builder instance */ - public GameMapBuilder getGameMapBuilder() { + @Override + public BaseMapBuilder getMapBuilder() { return this.gameMapBuilder; } } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/data/InstanceSetupData.java b/setup/src/main/java/net/theevilreaper/tamias/setup/data/InstanceSetupData.java index 16cbc597..36bba95c 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/data/InstanceSetupData.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/data/InstanceSetupData.java @@ -8,6 +8,7 @@ import net.minestom.server.entity.Player; import net.minestom.server.instance.InstanceContainer; import net.onelitefeather.guira.data.SetupData; +import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; import org.jetbrains.annotations.NotNull; @@ -37,8 +38,6 @@ public void updateTitle() { } public void teleport(@NotNull Player player) { - //Pos spawnPoint = map.getSpawnOrDefault(SPAWN_POINT); - // player.setInstance(this.instance, spawnPoint); player.showBossBar(this.bossBar); } @@ -60,4 +59,6 @@ public void reset() { public @NotNull UUID getId() { return this.uuid; } + + public abstract BaseMapBuilder getMapBuilder(); } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/data/LobbyData.java b/setup/src/main/java/net/theevilreaper/tamias/setup/data/LobbyData.java index 678a0b3e..4fefa34d 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/data/LobbyData.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/data/LobbyData.java @@ -2,9 +2,9 @@ import net.kyori.adventure.bossbar.BossBar; import net.minestom.server.MinecraftServer; +import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.minestom.server.instance.anvil.AnvilLoader; -import net.theevilreaper.aves.file.FileHandler; import net.theevilreaper.aves.map.BaseMap; import net.theevilreaper.aves.map.BaseMapBuilder; import net.theevilreaper.aves.map.MapEntry; @@ -15,15 +15,15 @@ import java.util.Optional; import java.util.UUID; +import static net.theevilreaper.tamias.setup.map.SetupMapProvider.FILE_HANDLER; + public final class LobbyData extends InstanceSetupData { - private final FileHandler fileHandler; private LobbyViewInventory viewInventory; private BaseMapBuilder mapBuilder; - public LobbyData(@NotNull UUID uuid, @NotNull MapEntry mapEntry, @NotNull FileHandler fileHandler) { + public LobbyData(@NotNull UUID uuid, @NotNull MapEntry mapEntry) { super(uuid, mapEntry, BossBar.Color.GREEN); - this.fileHandler = fileHandler; this.loadData(); Player player = MinecraftServer.getConnectionManager().getOnlinePlayerByUuid(uuid); @@ -49,7 +49,16 @@ public void save() { if (!Files.exists(mapEntry.getMapFile())) { this.mapEntry.createFile(); } - this.fileHandler.save(mapEntry.getMapFile(), BaseMap.class); + FILE_HANDLER.save(mapEntry.getMapFile(), BaseMap.class); + } + + @Override + public void teleport(@NotNull Player player) { + super.teleport(player); + Pos spawnPoint = this.mapBuilder.getSpawn() == null + ? SPAWN_POINT + : this.mapBuilder.getSpawn(); + player.setInstance(this.instance, spawnPoint); } @Override @@ -60,12 +69,15 @@ public void reset() { @Override public void loadData() { - if (this.mapEntry != null) return; - Optional mapData = fileHandler.load(mapEntry.getMapFile(), BaseMap.class); - - mapData.ifPresentOrElse(baseMap -> { - this.mapBuilder = BaseMap.builder(baseMap); - }, () -> this.mapBuilder = BaseMap.builder()); + if (this.mapEntry == null) { + this.mapBuilder = BaseMap.builder(); + } else { + Optional mapData = FILE_HANDLER.load(mapEntry.getMapFile(), BaseMap.class); + + mapData.ifPresentOrElse(baseMap -> { + this.mapBuilder = BaseMap.builder(baseMap); + }, () -> this.mapBuilder = BaseMap.builder()); + } this.viewInventory = new LobbyViewInventory(this.mapBuilder); @@ -76,6 +88,7 @@ public void loadData() { MinecraftServer.getInstanceManager().registerInstance(this.instance); } + @Override public BaseMapBuilder getMapBuilder() { return mapBuilder; } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/AbstractDialogTemplate.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/AbstractDialogTemplate.java new file mode 100644 index 00000000..f9397c83 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/AbstractDialogTemplate.java @@ -0,0 +1,20 @@ +package net.theevilreaper.tamias.setup.dialog; + +import net.kyori.adventure.text.Component; + +public abstract class AbstractDialogTemplate implements DialogTemplate { + + protected final Component header; + protected final Component submitComponent; + protected final Component cancelComponent; + + protected AbstractDialogTemplate( + Component header, + Component submitComponent, + Component cancelComponent + ) { + this.header = header; + this.submitComponent = submitComponent; + this.cancelComponent = cancelComponent; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogRegistry.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogRegistry.java new file mode 100644 index 00000000..9d747931 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogRegistry.java @@ -0,0 +1,11 @@ +package net.theevilreaper.tamias.setup.dialog; + +import net.kyori.adventure.key.Key; +import org.jetbrains.annotations.Nullable; + +public interface DialogRegistry { + + @Nullable DialogTemplate get(@Nullable Key key); + + boolean contains(Key key); +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogTemplate.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogTemplate.java new file mode 100644 index 00000000..b20c227e --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/DialogTemplate.java @@ -0,0 +1,22 @@ +package net.theevilreaper.tamias.setup.dialog; + +import net.kyori.adventure.key.Key; +import net.minestom.server.entity.Player; +import org.jetbrains.annotations.Nullable; + +public interface DialogTemplate { + + default void open(Player player) { + this.open(player, null); + } + + void open(Player player, @Nullable K data); + + /** + * Gets the key of this dialog template. + * + * @return the given key + */ + Key key(); + +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/SetupDialogRegistry.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/SetupDialogRegistry.java new file mode 100644 index 00000000..7735c8b4 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/SetupDialogRegistry.java @@ -0,0 +1,58 @@ +package net.theevilreaper.tamias.setup.dialog; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.text.Component; +import net.theevilreaper.tamias.setup.dialog.type.AuthorInputDialog; +import net.theevilreaper.tamias.setup.dialog.type.AuthorRequestDialog; +import net.theevilreaper.tamias.setup.dialog.type.DeleteDialog; +import net.theevilreaper.tamias.setup.dialog.type.NameInputDialog; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; + +public class SetupDialogRegistry implements DialogRegistry { + + private final Map> dialogMap; + + public SetupDialogRegistry() { + this.dialogMap = new HashMap<>(); + + Component saveButton = Component.text("Save"); + Component cancelButton = Component.text("Cancel"); + + this.registerDialog( + new NameInputDialog( + Component.text("Setup Map Name"), + saveButton, + cancelButton + ) + ); + this.registerDialog(new AuthorRequestDialog( + Component.text("Request Author(s)"), + saveButton, + cancelButton + )); + this.registerDialog(new AuthorInputDialog( + Component.text("Setup Author(s)"), + saveButton, + cancelButton + // Default to 1 author + )); + this.registerDialog(new DeleteDialog()); + } + + private void registerDialog(DialogTemplate dialog) { + dialogMap.put(dialog.key(), dialog); + } + + @Override + public @Nullable DialogTemplate get(@Nullable Key key) { + return this.dialogMap.getOrDefault(key, null); + } + + @Override + public boolean contains(Key key) { + return this.dialogMap.containsKey(key); + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDeletePromptEvent.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDeletePromptEvent.java new file mode 100644 index 00000000..59c32fe7 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDeletePromptEvent.java @@ -0,0 +1,34 @@ +package net.theevilreaper.tamias.setup.dialog.event; + +import net.minestom.server.entity.Player; +import net.minestom.server.event.trait.PlayerEvent; +import net.theevilreaper.tamias.setup.inventory.DataType; + +public class PlayerDeletePromptEvent implements PlayerEvent { + + private final Player player; + private final DataType type; + + public PlayerDeletePromptEvent(Player player, DataType type) { + this.player = player; + this.type = type; + } + + /** + * The involved data type + * + * @return the type of overview + */ + public DataType getType() { + return type; + } + + /** + * Gets the player who triggered the delete prompt event. + * + * @return the player who triggered the event + */ + public Player getPlayer() { + return this.player; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDialogRequestEvent.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDialogRequestEvent.java new file mode 100644 index 00000000..fd6b361f --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/PlayerDialogRequestEvent.java @@ -0,0 +1,64 @@ +package net.theevilreaper.tamias.setup.dialog.event; + +import net.minestom.server.entity.Player; +import net.minestom.server.event.trait.PlayerEvent; + +public class PlayerDialogRequestEvent implements PlayerEvent { + + private final Player player; + private final Target target; + + /** + * Constructs a new PlayerDialogRequestEvent instance. + * + * @param player the player who requested the dialog + * @param target the target of the dialog request + */ + public PlayerDialogRequestEvent(Player player, Target target) { + this.player = player; + this.target = target; + } + + /** + * Gets the target of the dialog request. + * + * @return the target of the dialog request + */ + public Target getTarget() { + return this.target; + } + + /** + * Gets the player who requested the dialog. + * + * @return the player who requested the dialog + */ + @Override + public Player getPlayer() { + return this.player; + } + + /** + * Represents the target of the dialog request. + */ + public enum Target { + /** + * The target for the dialog request is the setup name. + */ + SETUP_NAME, + /** + * The target for the dialog request is to define the amount of authors to set up. + */ + SETUP_REQUEST_AUTHOR, + /** + * The target for the dialog request is to define the author of the setup. + */ + SETUP_AUTHOR, + /** + * The target for the dialog request is to set up the block bounce. + */ + SETUP_BLOCK_BOUNCE + + ; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/package-info.java new file mode 100644 index 00000000..e22fff98 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/event/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.dialog.event; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/package-info.java new file mode 100644 index 00000000..9cd7d32d --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.dialog; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorInputDialog.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorInputDialog.java new file mode 100644 index 00000000..53e77b0c --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorInputDialog.java @@ -0,0 +1,90 @@ +package net.theevilreaper.tamias.setup.dialog.type; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.dialog.Dialog; +import net.minestom.server.dialog.DialogAction; +import net.minestom.server.dialog.DialogActionButton; +import net.minestom.server.dialog.DialogAfterAction; +import net.minestom.server.dialog.DialogBody; +import net.minestom.server.dialog.DialogInput; +import net.minestom.server.dialog.DialogMetadata; +import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.common.ShowDialogPacket; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import net.theevilreaper.tamias.setup.util.SetupTags; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class AuthorInputDialog implements DialogTemplate> { + + public static final Key DIALOG_KEY = Key.key("suicide", "bounce_author_setup"); + + private final Component header; + private final Component submitComponent; + private final Component cancelComponent; + + public AuthorInputDialog(Component header, Component submitComponent, Component cancelComponent) { + this.header = header; + this.submitComponent = submitComponent; + this.cancelComponent = cancelComponent; + } + + @Override + public void open(Player player, @Nullable List data) { + int amount = player.getTag(SetupTags.AUTHOR_AMOUNT_TAG); + List inputFields = new ArrayList<>(); + for (int i = 0; i < amount; i++) { + inputFields.add( + new DialogInput.Text( + "author" + i, + 200, + Component.text("Author " + i), + false, + "", + 32, + null + ) + ); + } + var packet = new ShowDialogPacket(new Dialog.Confirmation( + new DialogMetadata( + header, + null, + false, + false, + DialogAfterAction.CLOSE, + List.of( + new DialogBody.PlainMessage(Component.text("Please enter the builder(s)"), 200) + ), + inputFields + ), + new DialogActionButton( + submitComponent, + Component.text("Click to confirm", NamedTextColor.GREEN), + 100, + new DialogAction.DynamicCustom(DIALOG_KEY, + CompoundBinaryTag.builder() + .putInt("amount", amount) + .build() + ) + ), + new DialogActionButton( + cancelComponent, + Component.text("Click to cancel", NamedTextColor.RED), + 101, + null + ) + )); + player.sendPacket(packet); + } + + @Override + public Key key() { + return DIALOG_KEY; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorRequestDialog.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorRequestDialog.java new file mode 100644 index 00000000..d761da9b --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/AuthorRequestDialog.java @@ -0,0 +1,71 @@ +package net.theevilreaper.tamias.setup.dialog.type; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.dialog.Dialog; +import net.minestom.server.dialog.DialogAction; +import net.minestom.server.dialog.DialogActionButton; +import net.minestom.server.dialog.DialogAfterAction; +import net.minestom.server.dialog.DialogBody; +import net.minestom.server.dialog.DialogInput; +import net.minestom.server.dialog.DialogMetadata; +import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.common.ShowDialogPacket; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class AuthorRequestDialog implements DialogTemplate { + + public static final Key DIALOG_KEY = Key.key("suicide", "author_amount_dialog"); + + private final Component header; + private final Component submitComponent; + private final Component cancelComponent; + + public AuthorRequestDialog(Component header, Component submitComponent, Component cancelComponent) { + this.header = header; + this.submitComponent = submitComponent; + this.cancelComponent = cancelComponent; + } + + @Override + public void open(Player player, @Nullable Void data) { + var packet = new ShowDialogPacket(new Dialog.Confirmation( + new DialogMetadata( + header, + null, + false, + false, + DialogAfterAction.CLOSE, + List.of( + new DialogBody.PlainMessage(Component.text("How many builders should the map have?"), 200) + ), + List.of( + new DialogInput.NumberRange("amount", 200, Component.text("Amount"), "options.generic_value", 1, 10, 1f, 1f) + ) + ), + new DialogActionButton( + submitComponent, + Component.text("Click to confirm", NamedTextColor.GREEN), + 100, + new DialogAction.DynamicCustom(DIALOG_KEY, CompoundBinaryTag.builder().build()) + ), + new DialogActionButton( + cancelComponent, + Component.text("Click to cancel", NamedTextColor.RED), + 101, + null + ) + )); + player.sendPacket(packet); + } + + @Override + public Key key() { + return DIALOG_KEY; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/DeleteDialog.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/DeleteDialog.java new file mode 100644 index 00000000..b9b71b97 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/DeleteDialog.java @@ -0,0 +1,69 @@ +package net.theevilreaper.tamias.setup.dialog.type; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.dialog.Dialog; +import net.minestom.server.dialog.DialogAction; +import net.minestom.server.dialog.DialogActionButton; +import net.minestom.server.dialog.DialogAfterAction; +import net.minestom.server.dialog.DialogBody; +import net.minestom.server.dialog.DialogMetadata; +import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.common.ShowDialogPacket; +import net.theevilreaper.tamias.setup.dialog.AbstractDialogTemplate; +import net.theevilreaper.tamias.setup.inventory.DataType; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class DeleteDialog extends AbstractDialogTemplate { + + public static final Key DIALOG_KEY = Key.key("suicide", "delete_dialog"); + + public DeleteDialog() { + super(Component.text("Confirm data deletion"), Component.text("Yes"), Component.text("No")); + } + + @Override + public void open(Player player, @Nullable DataType data) { + var packet = new ShowDialogPacket(new Dialog.Confirmation( + new DialogMetadata( + header, + null, + false, + false, + DialogAfterAction.CLOSE, + List.of( + new DialogBody.PlainMessage(Component.text("The following map data would be deleted:"), 150), + new DialogBody.PlainMessage(Component.empty(), 1) + // new DialogBody.PlainMessage(Component.text(data == null ? "No data provided" : data.getName()), 100) + ), + List.of() + ), + new DialogActionButton( + submitComponent, + Component.text("Click to confirm", NamedTextColor.GREEN), + 100, + new DialogAction.DynamicCustom(DIALOG_KEY, CompoundBinaryTag + .builder() + .putInt("type", data.ordinal()) + .build() + ) + ), + new DialogActionButton( + cancelComponent, + Component.text("Click to cancel", NamedTextColor.RED), + 101, + null + ) + )); + player.sendPacket(packet); + } + + @Override + public Key key() { + return DIALOG_KEY; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/NameInputDialog.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/NameInputDialog.java new file mode 100644 index 00000000..f7592273 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/NameInputDialog.java @@ -0,0 +1,76 @@ +package net.theevilreaper.tamias.setup.dialog.type; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.kyori.adventure.text.Component; +import net.minestom.server.dialog.Dialog; +import net.minestom.server.dialog.DialogAction; +import net.minestom.server.dialog.DialogActionButton; +import net.minestom.server.dialog.DialogAfterAction; +import net.minestom.server.dialog.DialogBody; +import net.minestom.server.dialog.DialogInput; +import net.minestom.server.dialog.DialogMetadata; +import net.minestom.server.entity.Player; +import net.minestom.server.network.packet.server.common.ShowDialogPacket; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public final class NameInputDialog implements DialogTemplate { + + public static final Key DIALOG_KEY = Key.key("suicide", "name_setup_dialog"); + + private final Component header; + private final Component submitComponent; + private final Component cancelComponent; + + public NameInputDialog(Component header, Component submitComponent, Component cancelComponent) { + this.header = header; + this.submitComponent = submitComponent; + this.cancelComponent = cancelComponent; + } + + /** + * Opens the name input dialog for the given player with the provided data. + * + * @param player the player to open the dialog for + * @param data the initial data to pre-fill the input field, can be null + */ + public void open(Player player, @Nullable String data) { + String initialName = data == null ? "" : data; + var packet = new ShowDialogPacket(new Dialog.Confirmation( + new DialogMetadata( + header, + null, + false, + false, + DialogAfterAction.CLOSE, + List.of( + new DialogBody.PlainMessage(Component.text("How the name of the map should be?"), 200) + ), + List.of( + new DialogInput.Text("name", 200, Component.text("Name"), true, initialName, 32, null) + ) + ), + new DialogActionButton( + submitComponent, + Component.text("§7Click to submit"), + 100, + new DialogAction.DynamicCustom(DIALOG_KEY, CompoundBinaryTag.builder().build()) + ), + new DialogActionButton( + cancelComponent, + Component.text("§7Click to cancel"), + 101, + null + ) + )); + player.sendPacket(packet); + } + + @Override + public Key key() { + return DIALOG_KEY; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/package-info.java new file mode 100644 index 00000000..bee480a4 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/dialog/type/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.dialog.type; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/SetupDialogRequestEvent.java b/setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/SetupDialogRequestEvent.java deleted file mode 100644 index 4ebbe80a..00000000 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/event/dialog/SetupDialogRequestEvent.java +++ /dev/null @@ -1,84 +0,0 @@ -package net.theevilreaper.tamias.setup.event.dialog; - -import net.minestom.server.entity.Player; -import net.minestom.server.event.trait.CancellableEvent; -import net.minestom.server.event.trait.PlayerEvent; - -/** - * The {@link SetupDialogRequestEvent} is triggered when a player requests to open a setup dialog. - * This event is cancellable, allowing the server to prevent the dialog from being displayed. - * - * @author theEvilReaper - * @version 1.0.0 - * @since 0.1.0 - */ -public class SetupDialogRequestEvent implements PlayerEvent, CancellableEvent { - - private final Player player; - private final Type type; - private boolean cancelled; - - /** - * Constructs a new {@link SetupDialogRequestEvent}. - * - * @param player the player who triggered the event - * @param type the type of dialog to be opened - */ - public SetupDialogRequestEvent(Player player, Type type) { - this.player = player; - this.type = type; - this.cancelled = false; - } - - /** - * Sets whether the event is cancelled. - * - * @param cancel true to cancel the event, false otherwise - */ - @Override - public void setCancelled(boolean cancel) { - this.cancelled = cancel; - } - - /** - * Checks if the event has been cancelled. - * - * @return true if the event is cancelled, false otherwise - */ - @Override - public boolean isCancelled() { - return this.cancelled; - } - - /** - * Gets the player who requested the setup dialog. - * - * @return the player instance - */ - @Override - public Player getPlayer() { - return this.player; - } - - /** - * Gets the type of dialog that was requested. - * - * @return the type of dialog - */ - public Type getType() { - return type; - } - - /** - * Enum representing the types of setup dialogs that can be requested. - * - * @author theEvilReaper - * @version 1.0.0 - * @since 0.1.0 - */ - public enum Type { - - MAP_NAME, - MAP_AUTHORS, - } -} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventory.java b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventory.java deleted file mode 100644 index d1df043a..00000000 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventory.java +++ /dev/null @@ -1,74 +0,0 @@ -package net.theevilreaper.tamias.setup.inventory; - -import net.theevilreaper.aves.inventory.GlobalInventoryBuilder; -import net.theevilreaper.aves.inventory.InventoryLayout; -import net.theevilreaper.aves.inventory.click.ClickHolder; -import net.theevilreaper.aves.inventory.util.LayoutCalculator; -import net.theevilreaper.aves.util.functional.PlayerConsumer; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.entity.Player; -import net.minestom.server.event.EventDispatcher; -import net.minestom.server.event.inventory.InventoryCloseEvent; -import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; -import net.theevilreaper.tamias.setup.TamiasSetup; -import net.theevilreaper.tamias.setup.util.SetupItems; - -import static net.theevilreaper.aves.inventory.util.InventoryConstants.CANCEL_CLICK; - -@SuppressWarnings("java:S3252") -public class ConfirmInventory extends GlobalInventoryBuilder { - - private static final int[] DECO_SLOTS; - private static final int[] CONFIRM_SLOTS; - private static final int[] CANCEL_SLOTS; - - private static final ItemStack CONFIRM_STACK; - private static final ItemStack CANCEL_STACK; - - static { - DECO_SLOTS = LayoutCalculator.quad(0, InventoryType.CHEST_4_ROW.getSize() - 1); - CONFIRM_SLOTS = LayoutCalculator.from(10, 11, 19, 20); - CANCEL_SLOTS = LayoutCalculator.from(14, 15, 23, 24); - - CONFIRM_STACK = ItemStack.builder(Material.GREEN_CONCRETE) - .customName(Component.text("Confirm", NamedTextColor.GREEN)) - .build(); - - CANCEL_STACK = ItemStack.builder(Material.RED_CONCRETE) - .customName(Component.text("Cancel", NamedTextColor.RED)) - .build(); - } - - public ConfirmInventory(PlayerConsumer consumer) { - super(Component.text("Confirm"), InventoryType.CHEST_4_ROW); - - InventoryLayout layout = InventoryLayout.fromType(getType()); - layout.setItems(DECO_SLOTS, SetupItems.DECORATION, CANCEL_CLICK); - - layout.setItems(CONFIRM_SLOTS, CONFIRM_STACK, (player, i, click, stack, result) -> { - result.accept(ClickHolder.cancelClick()); - player.setTag(TamiasSetup.DELETE_TAG, true); - EventDispatcher.call(new InventoryCloseEvent(player.getOpenInventory(), player, false)); - player.closeInventory(); - }); - - layout.setItems(CANCEL_SLOTS, CANCEL_STACK, (player, i, click, stack, result) -> { - result.accept(ClickHolder.cancelClick()); - player.closeInventory(); - }); - - setLayout(layout); - - setCloseFunction(closeEvent -> { - Player player = closeEvent.getPlayer(); - if (!player.hasTag(TamiasSetup.DELETE_TAG)) return; - consumer.accept(player); - player.removeTag(TamiasSetup.DELETE_TAG); - }); - - this.invalidateDataLayout(); - } -} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/DataType.java b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/DataType.java index 77c7a918..3aba5f4b 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/DataType.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/DataType.java @@ -1,6 +1,7 @@ package net.theevilreaper.tamias.setup.inventory; import net.minestom.server.item.Material; +import org.jetbrains.annotations.Nullable; /** * The {@link DataType} enum contains all data types which can be selected in the setup process. @@ -12,10 +13,13 @@ @SuppressWarnings("java:S3252") public enum DataType { + NAME(Material.NAME_TAG), + AUTHOR(Material.OAK_SIGN), SPAWN(Material.GREEN_BED), BOMBER(Material.TNT), SURVIVOR(Material.GREEN_DYE); + private static final DataType[] VALUES = values(); private final Material material; /** @@ -35,5 +39,16 @@ public enum DataType { public Material getMaterial() { return material; } + + /** + * Returns the data type for the given ordinal. + * + * @param ordinal the ordinal + * @return the data type or null if the ordinal is out of range + */ + public static @Nullable DataType fromOrdinal(int ordinal) { + if (ordinal < 0 || ordinal >= VALUES.length) return null; + return VALUES[ordinal]; + } } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/LobbyViewInventory.java b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/LobbyViewInventory.java index a338159a..c6a717f7 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/LobbyViewInventory.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/LobbyViewInventory.java @@ -1,23 +1,27 @@ package net.theevilreaper.tamias.setup.inventory; +import net.minestom.server.coordinate.Point; +import net.minestom.server.event.EventDispatcher; import net.theevilreaper.aves.inventory.GlobalInventoryBuilder; import net.theevilreaper.aves.inventory.InventoryLayout; -import net.theevilreaper.aves.inventory.slot.ISlot; import net.theevilreaper.aves.inventory.util.LayoutCalculator; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; import net.minestom.server.inventory.InventoryType; -import net.minestom.server.item.ItemStack; -import net.minestom.server.item.Material; import net.theevilreaper.aves.map.BaseMapBuilder; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDeletePromptEvent; +import net.theevilreaper.tamias.setup.inventory.slot.EmptyItemSlot; import net.theevilreaper.tamias.setup.inventory.slot.MultipleStringItemSlot; import net.theevilreaper.tamias.setup.inventory.slot.SpawnItemSlot; import net.theevilreaper.tamias.setup.inventory.slot.StringItemSlot; import net.theevilreaper.tamias.setup.util.SetupItems; +import org.jetbrains.annotations.Nullable; + +import java.util.List; import static net.theevilreaper.aves.inventory.util.InventoryConstants.CANCEL_CLICK; +import static net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent.*; /** * The {@link LobbyViewInventory} is used to display the data from a lobby map. @@ -32,13 +36,7 @@ @SuppressWarnings("java:S3252") public class LobbyViewInventory extends GlobalInventoryBuilder { - private static final ItemStack NO_SPAWN = ItemStack.builder(Material.BARRIER) - .customName(Component.text("No spawn set", NamedTextColor.RED)) - .build(); - private static final int[] DATA_SLOTS = LayoutCalculator.from(11, 13, 15); - private final ConfirmInventory confirmInventory; - private final BaseMapBuilder mapBuilder; /** * Creates a new {@link LobbyViewInventory} instance. @@ -46,9 +44,7 @@ public class LobbyViewInventory extends GlobalInventoryBuilder { * @param mapBuilder the map to display */ public LobbyViewInventory(BaseMapBuilder mapBuilder) { - super(Component.text("Lobby data"), InventoryType.CHEST_3_ROW); - this.mapBuilder = mapBuilder; - this.confirmInventory = new ConfirmInventory(this::handleConfirmClick); + super(Component.text("Generic data"), InventoryType.CHEST_3_ROW); InventoryLayout layout = InventoryLayout.fromType(getType()); layout.setItems(LayoutCalculator.quad(0, getType().getSize() - 1), SetupItems.DECORATION, CANCEL_CLICK); this.setLayout(layout); @@ -56,25 +52,9 @@ public LobbyViewInventory(BaseMapBuilder mapBuilder) { this.setDataLayoutFunction(dataLayout -> { dataLayout = dataLayout == null ? InventoryLayout.fromType(getType()) : dataLayout; dataLayout.blank(DATA_SLOTS); - if (hasNoData()) { - dataLayout.setItem(DATA_SLOTS[0], SetupItems.DECORATION, CANCEL_CLICK); - dataLayout.setItem(DATA_SLOTS[1], NO_SPAWN, CANCEL_CLICK); - dataLayout.setItem(DATA_SLOTS[2], SetupItems.DECORATION, CANCEL_CLICK); - return dataLayout; - } - ISlot mapNameSlot = new StringItemSlot(Component.text("Map-Name", NamedTextColor.GOLD), mapBuilder.getName()); - ISlot builderSlot = new MultipleStringItemSlot(Component.text("Builders", NamedTextColor.GOLD), mapBuilder.getBuilders()); - ISlot spawnSlot; - - if (mapBuilder.getSpawn() != null) { - spawnSlot = SpawnItemSlot.empty(); - } else { - spawnSlot = SpawnItemSlot.asSpawn(mapBuilder.getSpawn(), this::openConfirmInventory); - } - - dataLayout.setItem(DATA_SLOTS[0], mapNameSlot, CANCEL_CLICK); - dataLayout.setItem(DATA_SLOTS[1], spawnSlot); - dataLayout.setItem(DATA_SLOTS[2], builderSlot, CANCEL_CLICK); + this.setMapNameItem(dataLayout, mapBuilder.getName()); + this.setSpawnItem(dataLayout, mapBuilder.getSpawn()); + this.setAuthorItem(dataLayout, mapBuilder.getBuilders()); return dataLayout; }); @@ -84,35 +64,54 @@ public LobbyViewInventory(BaseMapBuilder mapBuilder) { } /** - * Opens the confirmation inventory. + * Sets the map name item. * - * @param player the player to open the inventory + * @param dataLayout the layout which should receive the item + * @param name the name of the map */ - private void openConfirmInventory(Player player) { - player.closeInventory(); - confirmInventory.register(); - player.openInventory(confirmInventory.getInventory()); + private void setMapNameItem(InventoryLayout dataLayout, @Nullable String name) { + if (name == null) { + dataLayout.setItem(DATA_SLOTS[0], new EmptyItemSlot(Target.SETUP_NAME)); + return; + } + dataLayout.setItem(DATA_SLOTS[0], new StringItemSlot(Component.text("Name", NamedTextColor.GOLD), name)); } /** - * Handles the confirmation logic. + * Sets the spawn item. * - * @param player the player who clicked + * @param layout the layout which should receive the item + * @param spawn the spawn point */ - private void handleConfirmClick(Player player) { - player.closeInventory(); - mapBuilder.spawn(null); - invalidateDataLayout(); - MinecraftServer.getSchedulerManager().scheduleNextTick(() -> player.openInventory(this.getInventory())); + private void setSpawnItem(InventoryLayout layout, @Nullable Point spawn) { + if (spawn == null) { + layout.setItem(DATA_SLOTS[1], new EmptyItemSlot(Target.SETUP_BLOCK_BOUNCE)); + } else { + layout.setItem(DATA_SLOTS[1], SpawnItemSlot.asSpawn(spawn, this::openConfirmInventory)); + } } /** - * Checks if the map has no data. + * Sets the author item. * - * @return true if the map has no data otherwise false + * @param layout the layout which should receive the item + * @param author the author of the map */ - private boolean hasNoData() { - boolean hasMapName = this.mapBuilder.getName() != null && !this.mapBuilder.getName().isEmpty(); - return this.mapBuilder.getSpawn() != null && !hasMapName && (this.mapBuilder.getBuilders() == null || this.mapBuilder.getBuilders().isEmpty()); + private void setAuthorItem(InventoryLayout layout, @Nullable List author) { + if (author == null || author.isEmpty()) { + layout.setItem(DATA_SLOTS[2], new EmptyItemSlot(Target.SETUP_REQUEST_AUTHOR)); + } else { + layout.setItem(DATA_SLOTS[2], new MultipleStringItemSlot(Component.text("Author", NamedTextColor.GOLD), author)); + } + } + + /** + * Handles the delete request for the spawn item. + * + * @param player the player who should get the dialog + */ + private void openConfirmInventory(Player player) { + player.closeInventory(); + EventDispatcher.call(new PlayerDeletePromptEvent(player, DataType.SPAWN)); } } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/MapSetupInventory.java b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/MapSetupInventory.java index baebe3d7..1be7356b 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/MapSetupInventory.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/MapSetupInventory.java @@ -61,8 +61,8 @@ public MapSetupInventory(Supplier> maps) { List mapEntries = maps.get(); for (int i = 0; i < mapEntries.size(); i++) { var currentMap = mapEntries.get(i); - dataLayout.setItem(MAP_SLOTS[i], getMapItem(currentMap.getDirectoryRoot()), (player, slot, click, item, result) -> - this.handleClick(currentMap, player, slot, click, item, result)); + dataLayout.setItem(MAP_SLOTS[i], getMapItem(currentMap.getDirectoryRoot()), (player, _, click, _, result) -> + this.handleClick(currentMap, player, click, result)); } return dataLayout; }); @@ -75,16 +75,13 @@ public MapSetupInventory(Supplier> maps) { * * @param currentMap the current map being clicked * @param player the player who clicked - * @param slot the slot that was clicked * @param click the type of click (left, right, etc.) - * @param stack the item stack that was clicked * @param result a consumer to handle the result of the click */ - private ClickHolder handleClick(MapEntry currentMap, Player player, int slot, Click click, ItemStack stack, Consumer result) { + private void handleClick(MapEntry currentMap, Player player, Click click, Consumer result) { result.accept(ClickHolder.cancelClick()); boolean lobbyMode = click instanceof Click.Left; EventDispatcher.callCancellable(new MapSetupSelectEvent(player, currentMap, lobbyMode), player::closeInventory); - return ClickHolder.cancelClick(); } /** diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlot.java b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlot.java new file mode 100644 index 00000000..e78ac7ec --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlot.java @@ -0,0 +1,37 @@ +package net.theevilreaper.tamias.setup.inventory.slot; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.minestom.server.event.EventDispatcher; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.theevilreaper.aves.inventory.click.ClickHolder; +import net.theevilreaper.aves.inventory.slot.Slot; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent; + +public final class EmptyItemSlot extends Slot { + + private static final ItemStack STACK = ItemStack.builder(Material.BARRIER) + .customName(Component.text("No data set!", NamedTextColor.RED)) + .build(); + + /** + * Creates a new EmptyItemSlot that requests the given data type on click. + * + * @param target the data type to request on click + */ + public EmptyItemSlot(PlayerDialogRequestEvent.Target target) { + super((player, _, _, _, result) -> { + result.accept(ClickHolder.cancelClick()); + EventDispatcher.call(new PlayerDialogRequestEvent(player, target)); + }); + } + + /** + * {@inheritDoc} + */ + @Override + public ItemStack getItem() { + return STACK; + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerChatListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerChatListener.java index ee37b9ff..2c9c4513 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerChatListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerChatListener.java @@ -7,9 +7,8 @@ import net.onelitefeather.guira.SetupDataService; import net.onelitefeather.guira.data.SetupData; import net.theevilreaper.aves.map.BaseMap; -import net.theevilreaper.tamias.setup.TamiasSetup; import net.theevilreaper.tamias.setup.data.InstanceSetupData; -import org.jetbrains.annotations.NotNull; +import net.theevilreaper.tamias.setup.util.SetupTags; import java.util.function.Consumer; @@ -21,28 +20,28 @@ public final class PlayerChatListener implements Consumer { private final SetupDataService setupDataService; - public PlayerChatListener(@NotNull SetupDataService setupDataService) { + public PlayerChatListener(SetupDataService setupDataService) { this.setupDataService = setupDataService; } @Override - public void accept(@NotNull PlayerChatEvent event) { + public void accept(PlayerChatEvent event) { Player player = event.getPlayer(); - if (!player.hasTag(TamiasSetup.SETUP_TAG)) { + if (!player.hasTag(SetupTags.SETUP_TAG)) { event.setFormattedMessage(formatGeneral(event)); } else { event.setFormattedMessage(formatSetup(event)); } } - private @NotNull Component formatGeneral(@NotNull PlayerChatEvent event) { + private Component formatGeneral(PlayerChatEvent event) { Player player = event.getPlayer(); return Component.text(player.getUsername(), NamedTextColor.GREEN).append(Component.space()) .append(CHAT_SEPARATOR).append(Component.space()) .append(Component.text(event.getRawMessage(), NamedTextColor.GRAY)); } - private @NotNull Component formatSetup(@NotNull PlayerChatEvent event) { + private Component formatSetup(PlayerChatEvent event) { Player player = event.getPlayer(); Component general = formatGeneral(event); SetupData setupData = setupDataService.get(player.getUuid()).orElse(null); diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerConfigurationListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerConfigurationListener.java index a16d05c1..4eefd9db 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerConfigurationListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerConfigurationListener.java @@ -2,7 +2,6 @@ import net.minestom.server.event.player.AsyncPlayerConfigurationEvent; import net.minestom.server.instance.Instance; -import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; import java.util.function.Supplier; @@ -11,12 +10,12 @@ public final class PlayerConfigurationListener implements Consumer instanceSupplier; - public PlayerConfigurationListener(@NotNull Supplier instanceSupplier) { + public PlayerConfigurationListener(Supplier instanceSupplier) { this.instanceSupplier = instanceSupplier; } @Override - public void accept(@NotNull AsyncPlayerConfigurationEvent event) { + public void accept(AsyncPlayerConfigurationEvent event) { event.setSpawningInstance(this.instanceSupplier.get()); } } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerDisconnectListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerDisconnectListener.java index e5a4d2f8..1df12026 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerDisconnectListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerDisconnectListener.java @@ -8,7 +8,6 @@ import net.minestom.server.event.player.PlayerDisconnectEvent; import net.onelitefeather.guira.data.SetupData; import net.theevilreaper.tamias.common.util.Messages; -import org.jetbrains.annotations.NotNull; import java.util.Optional; import java.util.UUID; @@ -19,12 +18,12 @@ public final class PlayerDisconnectListener implements Consumer> dataRemover; - public PlayerDisconnectListener(@NotNull Function> dataRemover) { + public PlayerDisconnectListener(Function> dataRemover) { this.dataRemover = dataRemover; } @Override - public void accept(@NotNull PlayerDisconnectEvent event) { + public void accept(PlayerDisconnectEvent event) { Player player = event.getPlayer(); Component joinMessage = Messages.withPrefix(Component.text(player.getUsername(), NamedTextColor.AQUA)) .append(Component.space()) diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerSpawnListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerSpawnListener.java index 6a378014..d00a9598 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerSpawnListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/PlayerSpawnListener.java @@ -8,7 +8,6 @@ import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerSpawnEvent; import net.theevilreaper.tamias.common.util.Messages; -import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -16,12 +15,12 @@ public final class PlayerSpawnListener implements Consumer { private final PlayerConsumer spawnSupplier; - public PlayerSpawnListener(@NotNull PlayerConsumer spawnSupplier) { + public PlayerSpawnListener(PlayerConsumer spawnSupplier) { this.spawnSupplier = spawnSupplier; } @Override - public void accept(@NotNull PlayerSpawnEvent event) { + public void accept(PlayerSpawnEvent event) { Player player = event.getPlayer(); if (event.isFirstSpawn()) { diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerCustomClickEventListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerCustomClickEventListener.java new file mode 100644 index 00000000..647af07b --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerCustomClickEventListener.java @@ -0,0 +1,114 @@ +package net.theevilreaper.tamias.setup.listener.dialog; + +import net.kyori.adventure.key.Key; +import net.kyori.adventure.nbt.BinaryTag; +import net.kyori.adventure.nbt.CompoundBinaryTag; +import net.minestom.server.entity.Player; +import net.minestom.server.event.player.PlayerCustomClickEvent; +import net.onelitefeather.guira.functional.OptionalSetupDataGetter; +import net.theevilreaper.tamias.setup.data.InstanceSetupData; +import net.theevilreaper.tamias.setup.dialog.DialogRegistry; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import net.theevilreaper.tamias.setup.dialog.type.AuthorInputDialog; +import net.theevilreaper.tamias.setup.dialog.type.AuthorRequestDialog; +import net.theevilreaper.tamias.setup.dialog.type.DeleteDialog; +import net.theevilreaper.tamias.setup.dialog.type.NameInputDialog; +import net.theevilreaper.tamias.setup.inventory.DataType; +import net.theevilreaper.tamias.setup.util.SetupTags; + +import java.util.function.Consumer; + +public class PlayerCustomClickEventListener implements Consumer { + + private final DialogRegistry dialogRegistry; + private final OptionalSetupDataGetter setupDataGetter; + + public PlayerCustomClickEventListener(DialogRegistry dialogRegistry, OptionalSetupDataGetter setupDataGetter) { + this.dialogRegistry = dialogRegistry; + this.setupDataGetter = setupDataGetter; + } + + @Override + public void accept(PlayerCustomClickEvent event) { + Player player = event.getPlayer(); + + if (!player.hasTag(SetupTags.SETUP_TAG)) return; + + Key key = event.getKey(); + BinaryTag payload = event.getPayload(); + + if (payload == null) return; + + DialogTemplate dialogTemplate = dialogRegistry.get(key); + + if (dialogTemplate == null) return; + + CompoundBinaryTag dialogData = (CompoundBinaryTag) payload; + + if (dialogTemplate instanceof AuthorRequestDialog) { + int amount = dialogData.getInt("amount", 1); + player.setTag(SetupTags.AUTHOR_AMOUNT_TAG, amount); + dialogRegistry.get(AuthorInputDialog.DIALOG_KEY).open(player); + return; + } + + setupDataGetter.get(player.getUuid()).ifPresent(setupData -> { + InstanceSetupData data = (InstanceSetupData) setupData; + + switch (dialogTemplate) { + case NameInputDialog _ -> this.handleNameSet(data, dialogData); + case AuthorInputDialog _ -> handleAuthorSet(data, dialogData); + case DeleteDialog _ -> this.handleDataDelete(data, dialogData); + default -> + throw new IllegalStateException("Unexpected dialog type: " + dialogTemplate.getClass().getCanonicalName()); + } + }); + } + + /** + * Handles the setting of authors based on the dialog data provided. + * + * @param data the BounceData instance containing the map builder + * @param dialogData the dialog data containing the authors to set + */ + private void handleNameSet(InstanceSetupData data, CompoundBinaryTag dialogData) { + String name = dialogData.getString("name"); + if (name.trim().isEmpty()) return; + data.getMapBuilder().name(name); + data.triggerUpdate(); + } + + /** + * Handles the setting of authors based on the dialog data provided. + * + * @param data the BounceData instance containing the map builder + * @param dialogData the dialog data containing the authors to set + */ + private void handleAuthorSet(InstanceSetupData data, CompoundBinaryTag dialogData) { + int amount = dialogData.getInt("amount", 1); + + for (int i = 0; i < amount; i++) { + String author = dialogData.getString("author" + i); + if (author.trim().isEmpty()) continue; + data.getMapBuilder().builder(author); + } + data.triggerUpdate(); + } + + /** + * Handles the deletion of data based on the dialog data provided. + * + * @param data the BounceData instance containing the map builder + * @param dialogData the dialog data containing the type of data to delete + */ + private void handleDataDelete(InstanceSetupData data, CompoundBinaryTag dialogData) { + int type = dialogData.getInt("type"); + DataType mappedType = DataType.fromOrdinal(type); + switch (mappedType) { + case NAME -> data.getMapBuilder().name(null); + case SPAWN -> data.getMapBuilder().spawn(null); + } + + data.triggerUpdate(); + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDeletePromptListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDeletePromptListener.java new file mode 100644 index 00000000..9884e85e --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDeletePromptListener.java @@ -0,0 +1,31 @@ +package net.theevilreaper.tamias.setup.listener.dialog; + +import net.theevilreaper.tamias.setup.dialog.DialogRegistry; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDeletePromptEvent; +import net.theevilreaper.tamias.setup.dialog.type.DeleteDialog; + +import java.util.function.Consumer; + +public class PlayerDeletePromptListener implements Consumer { + + private final DialogRegistry dialogRegistry; + + public PlayerDeletePromptListener(DialogRegistry dialogRegistry) { + this.dialogRegistry = dialogRegistry; + } + + @Override + public void accept(PlayerDeletePromptEvent event) { + DialogTemplate dialog = dialogRegistry.get(DeleteDialog.DIALOG_KEY); + + if (dialog == null) { + throw new IllegalStateException("Dialog with key " + DeleteDialog.DIALOG_KEY + " not found in registry."); + } + + switch (dialog) { + case DeleteDialog deleteDialog -> deleteDialog.open(event.getPlayer(), event.getType()); + default -> throw new IllegalStateException("Unexpected dialog type: " + dialog.getClass().getCanonicalName()); + } + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDialogRequestListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDialogRequestListener.java new file mode 100644 index 00000000..d70d1104 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/PlayerDialogRequestListener.java @@ -0,0 +1,42 @@ +package net.theevilreaper.tamias.setup.listener.dialog; + +import net.minestom.server.entity.Player; +import net.theevilreaper.tamias.setup.dialog.DialogRegistry; +import net.theevilreaper.tamias.setup.dialog.DialogTemplate; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent; +import net.theevilreaper.tamias.setup.dialog.type.AuthorInputDialog; +import net.theevilreaper.tamias.setup.dialog.type.AuthorRequestDialog; +import net.theevilreaper.tamias.setup.dialog.type.NameInputDialog; + +import java.util.function.Consumer; + +import static net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent.*; + +public final class PlayerDialogRequestListener implements Consumer { + + private final DialogRegistry dialogRegistry; + + public PlayerDialogRequestListener(DialogRegistry dialogRegistry) { + this.dialogRegistry = dialogRegistry; + } + + @Override + public void accept(PlayerDialogRequestEvent event) { + Player player = event.getPlayer(); + Target target = event.getTarget(); + DialogTemplate dialogTemplate; + + switch (target) { + case Target.SETUP_NAME -> dialogTemplate = dialogRegistry.get(NameInputDialog.DIALOG_KEY); + case Target.SETUP_AUTHOR -> dialogTemplate = dialogRegistry.get(AuthorInputDialog.DIALOG_KEY); + case Target.SETUP_REQUEST_AUTHOR -> dialogTemplate = dialogRegistry.get(AuthorRequestDialog.DIALOG_KEY); + default -> throw new IllegalArgumentException("Unknown target: " + target); + } + + if (dialogTemplate == null) { + throw new IllegalStateException("Dialog with key " + dialogTemplate.key() + " not found in registry."); + } + + dialogTemplate.open(player); + } +} diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/package-info.java new file mode 100644 index 00000000..8e933b4e --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/dialog/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.listener.dialog; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/EntityAddToInstanceListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/EntityAddToInstanceListener.java index 611f7bc4..f7628c50 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/EntityAddToInstanceListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/EntityAddToInstanceListener.java @@ -4,7 +4,6 @@ import net.minestom.server.event.instance.AddEntityToInstanceEvent; import net.minestom.server.instance.Instance; import net.theevilreaper.tamias.setup.util.SetupItems; -import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; import java.util.function.Supplier; @@ -14,13 +13,13 @@ public class EntityAddToInstanceListener implements Consumer instanceSupplier; private final SetupItems items; - public EntityAddToInstanceListener(@NotNull Supplier instanceSupplier, @NotNull SetupItems items) { + public EntityAddToInstanceListener(Supplier instanceSupplier, SetupItems items) { this.instanceSupplier = instanceSupplier; this.items = items; } @Override - public void accept(@NotNull AddEntityToInstanceEvent event) { + public void accept(AddEntityToInstanceEvent event) { if (!(event.getEntity() instanceof Player player)) return; Instance mainInstance = this.instanceSupplier.get(); if (event.getInstance().getUuid().equals(mainInstance.getUuid())) { diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/package-info.java new file mode 100644 index 00000000..05b28d56 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/entity/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.listener.entity; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/PlayerUseItemListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/PlayerUseItemListener.java index ed63eb6e..6d3a8ef7 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/PlayerUseItemListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/PlayerUseItemListener.java @@ -8,9 +8,8 @@ import net.minestom.server.event.player.PlayerUseItemEvent; import net.minestom.server.item.ItemStack; import net.theevilreaper.tamias.common.util.Tags; -import net.theevilreaper.tamias.setup.TamiasSetup; import net.theevilreaper.tamias.setup.data.InstanceSetupData; -import org.jetbrains.annotations.NotNull; +import net.theevilreaper.tamias.setup.util.SetupTags; import java.util.Optional; import java.util.UUID; @@ -25,15 +24,15 @@ public final class PlayerUseItemListener implements Consumer private final Function> saveFunction; public PlayerUseItemListener( - @NotNull PlayerConsumer invOpener, - @NotNull Function> saveFunction + PlayerConsumer invOpener, + Function> saveFunction ) { this.invOpener = invOpener; this.saveFunction = saveFunction; } @Override - public void accept(@NotNull PlayerUseItemEvent event) { + public void accept(PlayerUseItemEvent event) { ItemStack stack = event.getItemStack(); if (!stack.hasTag(Tags.ITEM_TAG)) return; @@ -46,7 +45,7 @@ public void accept(@NotNull PlayerUseItemEvent event) { return; } - if (!player.hasTag(TamiasSetup.SETUP_TAG)) return; + if (!player.hasTag(SetupTags.SETUP_TAG)) return; Optional fetchedData = this.saveFunction.apply(player.getUuid()); if (fetchedData.isEmpty()) return; diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/package-info.java new file mode 100644 index 00000000..eb642645 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/item/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.listener.item; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/MapSetupSelectListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/MapSetupSelectListener.java index 7ffb0dbf..0eb85e91 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/MapSetupSelectListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/MapSetupSelectListener.java @@ -2,7 +2,6 @@ import net.onelitefeather.guira.SetupDataService; import net.onelitefeather.guira.data.SetupData; -import net.theevilreaper.aves.file.FileHandler; import net.theevilreaper.aves.map.MapEntry; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -11,46 +10,42 @@ import net.minestom.server.entity.Player; import net.minestom.server.timer.Task; import net.theevilreaper.tamias.common.util.Messages; -import net.theevilreaper.tamias.setup.TamiasSetup; import net.theevilreaper.tamias.setup.data.GameData; import net.theevilreaper.tamias.setup.data.InstanceSetupData; import net.theevilreaper.tamias.setup.data.LobbyData; import net.theevilreaper.tamias.setup.event.MapSetupSelectEvent; -import org.jetbrains.annotations.NotNull; +import net.theevilreaper.tamias.setup.util.SetupTags; import java.time.temporal.ChronoUnit; +import java.util.Optional; import java.util.function.Consumer; +import static net.theevilreaper.tamias.setup.map.SetupMapProvider.FILE_HANDLER; + public final class MapSetupSelectListener implements Consumer { - private final FileHandler fileHandler; private final SetupDataService setupDataService; - public MapSetupSelectListener( - @NotNull FileHandler fileHandler, - @NotNull SetupDataService setupDataService - ) { - this.fileHandler = fileHandler; + public MapSetupSelectListener(SetupDataService setupDataService) { this.setupDataService = setupDataService; } @Override - public void accept(@NotNull MapSetupSelectEvent event) { + public void accept(MapSetupSelectEvent event) { Player player = event.getPlayer(); - SetupData setupData = this.setupDataService.get(player.getUuid()).get(); + Optional setupData = this.setupDataService.get(player.getUuid()); - /*if (setupData != null && setupData.hasMap()) { - // If this condition is reached the setup is fucked up + if (setupData.isPresent()) { player.sendMessage("You already have a map selected"); - }*/ + } InstanceSetupData data; MapEntry mapEntry = event.getMapEntry(); if (event.isLobbyMode()) { - data = new LobbyData(player.getUuid(), mapEntry, this.fileHandler); + data = new LobbyData(player.getUuid(), mapEntry); } else { - data = new GameData(player.getUuid(), mapEntry, this.fileHandler); + data = new GameData(player.getUuid(), mapEntry); } Component message = Messages.withPrefix(Component.text("You selected the map: ", NamedTextColor.GRAY)) @@ -63,11 +58,17 @@ public void accept(@NotNull MapSetupSelectEvent event) { this.setupDataService.add(player.getUuid(), data); - player.setTag(TamiasSetup.SETUP_TAG, (byte) 1); + player.setTag(SetupTags.SETUP_TAG, 1); getTeleportTask(() -> data.teleport(player)).schedule(); } - private @NotNull Task.Builder getTeleportTask(@NotNull Runnable runnable) { + /** + * Creates a task that teleports the player after a delay of 3 seconds. + * + * @param runnable the runnable to execute after the delay, which should contain the teleportation logic + * @return a Task.Builder that can be scheduled to execute the teleportation after the specified delay + */ + private Task.Builder getTeleportTask(Runnable runnable) { return MinecraftServer.getSchedulerManager().buildTask(runnable).delay(3, ChronoUnit.SECONDS); } } diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/SetupFinishListener.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/SetupFinishListener.java index 8f976f58..f72d5907 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/SetupFinishListener.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/SetupFinishListener.java @@ -5,7 +5,6 @@ import net.onelitefeather.guira.data.SetupData; import net.onelitefeather.guira.event.SetupFinishEvent; import net.theevilreaper.aves.util.functional.PlayerConsumer; -import org.jetbrains.annotations.NotNull; import java.util.function.Consumer; @@ -13,12 +12,12 @@ public class SetupFinishListener implements Consumer { private final PlayerConsumer instanceSwitcher; - public SetupFinishListener(@NotNull PlayerConsumer instanceSwitcher) { + public SetupFinishListener(PlayerConsumer instanceSwitcher) { this.instanceSwitcher = instanceSwitcher; } @Override - public void accept(@NotNull SetupFinishEvent event) { + public void accept(SetupFinishEvent event) { SetupData setupData = event.getData(); setupData.save(); diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/package-info.java new file mode 100644 index 00000000..b5002a7a --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/map/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.listener.map; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/listener/package-info.java b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/package-info.java new file mode 100644 index 00000000..f25475e8 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/listener/package-info.java @@ -0,0 +1,4 @@ +@NotNullByDefault +package net.theevilreaper.tamias.setup.listener; + +import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/map/SetupMapProvider.java b/setup/src/main/java/net/theevilreaper/tamias/setup/map/SetupMapProvider.java index 1febab0d..b40017fe 100644 --- a/setup/src/main/java/net/theevilreaper/tamias/setup/map/SetupMapProvider.java +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/map/SetupMapProvider.java @@ -4,9 +4,11 @@ import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; import net.theevilreaper.aves.file.FileHandler; +import net.theevilreaper.aves.file.GsonFileHandler; import net.theevilreaper.aves.map.BaseMap; import net.theevilreaper.aves.map.MapEntry; import net.theevilreaper.aves.map.provider.AbstractMapProvider; +import net.theevilreaper.tamias.common.gson.GsonUtil; import net.theevilreaper.tamias.common.map.GameMap; import net.theevilreaper.tamias.common.map.functional.LobbyMapPredicate; import net.theevilreaper.tamias.common.util.MapFilter; @@ -23,18 +25,17 @@ */ public final class SetupMapProvider extends AbstractMapProvider { + public static final FileHandler FILE_HANDLER = new GsonFileHandler(GsonUtil.GSON); private static final Pos FALLBACK_POS = new Pos(0, 100, 0); - private static final String LOBBY_SUFFIX = "lobby"; // Constant for lobby suffix /** * Constructs a SetupMapProvider with the specified FileHandler. * * @param path the path where the maps are stored - * @param fileHandler the FileHandler used to load and save maps */ - public SetupMapProvider(Path path, FileHandler fileHandler) { - super(fileHandler, MapFilter::filterMapsForSetup); - loadMapEntries(path.resolve("maps")); + public SetupMapProvider(Path path) { + super(FILE_HANDLER, MapFilter::filterMapsForSetup); + this.mapEntries = loadMapEntries(path.resolve("maps")); LobbyMapPredicate predicate = new LobbyMapPredicate(); Optional lobbyEntry = getEntries().stream().filter(predicate).findFirst(); @@ -60,17 +61,6 @@ public SetupMapProvider(Path path, FileHandler fileHandler) { this.registerInstance(this.activeInstance, lobbyEntry.get()); } - - /** - * Checks if the given map is a lobby map. - * - * @param mapEntry the map entry to check - * @return true if the map is a lobby map - */ - private boolean isLobbyMap(MapEntry mapEntry) { - return mapEntry.getDirectoryRoot().endsWith(LOBBY_SUFFIX); - } - @Override public void saveMap(Path path, BaseMap baseMap) { this.fileHandler.save(path, baseMap instanceof GameMap mapToSave ? mapToSave : baseMap); diff --git a/setup/src/main/java/net/theevilreaper/tamias/setup/util/SetupTags.java b/setup/src/main/java/net/theevilreaper/tamias/setup/util/SetupTags.java new file mode 100644 index 00000000..d72f09c0 --- /dev/null +++ b/setup/src/main/java/net/theevilreaper/tamias/setup/util/SetupTags.java @@ -0,0 +1,13 @@ +package net.theevilreaper.tamias.setup.util; + +import net.minestom.server.tag.Tag; + +public class SetupTags { + + public static final Tag SETUP_TAG = Tag.Transient("suicide.setup"); + public static final Tag AUTHOR_AMOUNT_TAG = Tag.Transient("suicide.author_amount"); + + private SetupTags() { + + } +} diff --git a/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventoryIntegrationTest.java b/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventoryIntegrationTest.java deleted file mode 100644 index 257c5a2c..00000000 --- a/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/ConfirmInventoryIntegrationTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package net.theevilreaper.tamias.setup.inventory; - -import net.minestom.server.inventory.AbstractInventory; -import net.theevilreaper.aves.inventory.InventoryLayout; -import net.theevilreaper.aves.inventory.slot.ISlot; -import net.theevilreaper.aves.util.functional.PlayerConsumer; -import net.minestom.server.coordinate.Pos; -import net.minestom.server.entity.Player; -import net.minestom.server.instance.Instance; -import net.minestom.server.item.ItemStack; -import net.minestom.server.network.packet.server.play.OpenWindowPacket; -import net.minestom.server.network.packet.server.play.WindowItemsPacket; -import net.minestom.testing.Collector; -import net.minestom.testing.Env; -import net.minestom.testing.TestConnection; -import net.minestom.testing.extension.MicrotusExtension; -import org.jetbrains.annotations.NotNull; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; - -import java.util.List; - -import static org.junit.jupiter.api.Assertions.*; - -@ExtendWith(MicrotusExtension.class) -class ConfirmInventoryIntegrationTest { - - @Test - void testConfirmInventory(@NotNull Env env) { - Instance instance = env.createFlatInstance(); - TestConnection connection = env.createConnection(); - Player player = connection.connect(instance, Pos.ZERO); - PlayerConsumer consumer = pConsumer -> { - assertEquals(player, pConsumer); - }; - ConfirmInventory confirmInventory = new ConfirmInventory(consumer); - - Collector windowPacketCollector = connection.trackIncoming(OpenWindowPacket.class); - Collector windowItemsPacketCollector = connection.trackIncoming(WindowItemsPacket.class); - - player.openInventory(confirmInventory.getInventory()); - - windowPacketCollector.assertSingle(); - windowItemsPacketCollector.assertSingle(); - - AbstractInventory inventory = player.getOpenInventory(); - - assertNotNull(inventory); - - List packets = windowPacketCollector.collect(); - List itemsPackets = windowItemsPacketCollector.collect(); - - windowPacketCollector.assertCount(1); - windowItemsPacketCollector.assertCount(1); - - assertEquals(1, packets.size(), "The packet size must be at least 1"); - assertEquals(1, itemsPackets.size(), "There should only be one item list"); - - OpenWindowPacket windowPacket = packets.getFirst(); - - assertEquals(inventory.getWindowId(), windowPacket.windowId()); - //assertEquals(inventory.getTitle(), windowPacket.title()); - - int size = confirmInventory.getType().getSize(); - - InventoryLayout layout = confirmInventory.getLayout(); - List packetItems = itemsPackets.getFirst().items(); - assertNotNull(layout); - assertNotNull(packetItems); - - assertEquals(size, packetItems.size()); - assertEquals(size, layout.getSize()); - - for (int i = 0; i < size; i++) { - ISlot originalSlot = layout.getSlot(i); - assertNotNull(originalSlot); - - ItemStack packetItem = packetItems.get(i); - assertNotNull(packetItem); - assertEquals(originalSlot.getItem().material(), packetItem.material()); - } - - env.destroyInstance(instance, true); - confirmInventory.unregister(); - } -} diff --git a/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/DataTypeTest.java b/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/DataTypeTest.java new file mode 100644 index 00000000..98d74817 --- /dev/null +++ b/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/DataTypeTest.java @@ -0,0 +1,21 @@ +package net.theevilreaper.tamias.setup.inventory; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.junit.jupiter.api.Assertions.*; + +class DataTypeTest { + + @ParameterizedTest(name = "Test valid ordinal value {0}") + @ValueSource(ints = {0,1,2,3, 4}) + void testFromOrdinal(int value) { + assertNotNull(DataType.fromOrdinal(value)); + } + + @ParameterizedTest(name = "Test invalid ordinal value {0}") + @ValueSource(ints = {-1, 5}) + void testInvalidFromOrdinal(int value) { + assertNull(DataType.fromOrdinal(value)); + } +} diff --git a/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlotTest.java b/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlotTest.java new file mode 100644 index 00000000..c1a76ced --- /dev/null +++ b/setup/src/test/java/net/theevilreaper/tamias/setup/inventory/slot/EmptyItemSlotTest.java @@ -0,0 +1,38 @@ +package net.theevilreaper.tamias.setup.inventory.slot; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.minestom.server.component.DataComponents; +import net.minestom.server.item.ItemStack; +import net.minestom.server.item.Material; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import net.theevilreaper.tamias.setup.dialog.event.PlayerDialogRequestEvent; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static org.junit.jupiter.api.Assertions.*; + +@ExtendWith(MicrotusExtension.class) +class EmptyItemSlotTest { + + @Test + void testEmptySlot(@NotNull Env env) { + EmptyItemSlot emptyItemSlot = new EmptyItemSlot(PlayerDialogRequestEvent.Target.SETUP_NAME); + + assertNotNull(emptyItemSlot); + assertNotNull(emptyItemSlot.getClick(), "The click can not be null"); + assertNotNull(emptyItemSlot.getItem(), "The item can not be null"); + + ItemStack slotItem = emptyItemSlot.getItem(); + assertEquals(Material.BARRIER, slotItem.material(), "The material must be BARRIER"); + + assertTrue(slotItem.has(DataComponents.CUSTOM_NAME)); + Component displayName = slotItem.get(DataComponents.CUSTOM_NAME); + assertNotNull(displayName); + + String data = PlainTextComponentSerializer.plainText().serialize(displayName); + assertEquals("No data set!", data); + } +}