diff --git a/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java b/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java index baf1fdae..e2375a85 100644 --- a/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java +++ b/common/src/main/java/net/onelitefeather/cygnus/common/map/GameMapBuilder.java @@ -7,8 +7,10 @@ import net.theevilreaper.aves.map.BaseMapBuilder; import org.jetbrains.annotations.Nullable; +import java.util.Comparator; import java.util.HashSet; import java.util.Set; +import java.util.TreeSet; public final class GameMapBuilder extends BaseMapBuilder { @@ -22,7 +24,11 @@ public final class GameMapBuilder extends BaseMapBuilder { public GameMapBuilder() { super(); this.pageFaces = new HashSet<>(); - this.survivorSpawns = new HashSet<>(); + this.survivorSpawns = new TreeSet<>( + Comparator.comparingInt(Pos::blockX) + .thenComparingInt(Pos::blockY) + .thenComparingInt(Pos::blockZ) + ); } /** @@ -33,7 +39,11 @@ public GameMapBuilder() { public GameMapBuilder(GameMap gameMap) { super(gameMap); this.slenderSpawn = gameMap.getSlenderSpawn(); - this.survivorSpawns = gameMap.getSurvivorSpawns(); + this.survivorSpawns = new TreeSet<>( + Comparator.comparingInt(Pos::blockX) + .thenComparingInt(Pos::blockY) + .thenComparingInt(Pos::blockZ) + ); this.pageFaces = gameMap.getPageFaces(); } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java index f4423491..3cedec10 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/SetupExtension.java @@ -2,6 +2,7 @@ import net.minestom.server.MinecraftServer; import net.minestom.server.coordinate.Pos; +import net.minestom.server.event.EventListener; import net.minestom.server.event.GlobalEventHandler; import net.minestom.server.event.instance.AddEntityToInstanceEvent; import net.minestom.server.event.instance.RemoveEntityFromInstanceEvent; @@ -13,7 +14,6 @@ import net.minestom.server.event.player.PlayerUseItemEvent; import net.onelitefeather.cygnus.common.ListenerHandling; import net.minestom.server.instance.Instance; -import net.onelitefeather.cygnus.setup.command.SetupCommand; import net.onelitefeather.cygnus.setup.event.MapSetupSaveEvent; import net.onelitefeather.cygnus.setup.event.MapSetupSelectEvent; import net.onelitefeather.cygnus.setup.event.PositionSetEvent; @@ -25,6 +25,7 @@ import net.onelitefeather.cygnus.setup.listener.PageCreationListener; import net.onelitefeather.cygnus.setup.listener.PlayerSpawnListener; import net.onelitefeather.cygnus.setup.listener.SetupItemListener; +import net.onelitefeather.cygnus.setup.listener.SpawnCreationListener; import net.onelitefeather.cygnus.setup.listener.dialog.DialogPayloadListener; import net.onelitefeather.cygnus.setup.listener.dialog.DialogRequestListener; import net.onelitefeather.cygnus.setup.listener.map.MapSetupSaveListener; @@ -56,7 +57,6 @@ private void registerSetupComponents() { var manager = MinecraftServer.getGlobalEventHandler(); var commandManager = MinecraftServer.getCommandManager(); var spawnPos = new Pos(0, 150, 0); - commandManager.register(new SetupCommand(setupData)); Supplier instanceSupplier = this.mapProvider.getActiveInstance(); UUID instanceUUID = instanceSupplier.get().getUuid(); @@ -71,7 +71,10 @@ private void registerSetupComponents() { this.dataService.remove(event.getPlayer().getUuid()); }); manager.addListener(PlayerBlockBreakEvent.class, new PageCreationListener(this.dataService)); - + manager.addListener(EventListener.builder(PlayerBlockBreakEvent.class) + .ignoreCancelled(false) + .handler(new SpawnCreationListener(this.dataService)) + .build()); manager.addListener(AddEntityToInstanceEvent.class, new InstanceAddListener(instanceUUID)); manager.addListener(RemoveEntityFromInstanceEvent.class, new InstanceRemoveListener(instanceUUID)); registerCancelListener(manager); diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java deleted file mode 100644 index 7a9e0619..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/SetupCommand.java +++ /dev/null @@ -1,55 +0,0 @@ -package net.onelitefeather.cygnus.setup.command; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.condition.Conditions; -import net.onelitefeather.cygnus.common.Messages; -import net.onelitefeather.cygnus.setup.command.parts.SetupSurvivorSpawnCommand; -import net.onelitefeather.cygnus.setup.util.SetupData; - -/** - * The setup command class is the root node for all setup commands. - * It contains all subcommands to set up the game. - * The setup command is only available for players. - * - * @author theEvilReaper - * @version 1.0.0 - * @since 1.0.0 - */ -public final class SetupCommand extends Command { - - /** - * Creates a new instance from the command class and contains also the logic to execute the command. - * - * @param setupData the involved {@link SetupData} class to get some information from it - */ - public SetupCommand(SetupData setupData) { - super("setup"); - this.setCondition(Conditions::playerOnly); - this.addSubcommand(new SetupSurvivorSpawnCommand(setupData)); - Component helpMessage = getHelpComponent(); - this.setDefaultExecutor((sender, context) -> sender.sendMessage(helpMessage)); - } - - /** - * Returns the help component for the setup command. - * - * @return the help component - */ - private Component getHelpComponent() { - Component helpComponent = Messages.withPrefix(Component.text("Help for the setup commands:", NamedTextColor.GRAY)) - .append(Component.newline()); - - for (int i = 0; i < getSubcommands().size(); i++) { - Command subCommand = getSubcommands().get(i); - Component component = Messages.withPrefix(Component.text("- ", NamedTextColor.GRAY)) - .append(Component.text("/setup", NamedTextColor.YELLOW)) - .append(Component.space()) - .append(Component.text(subCommand.getName(), NamedTextColor.GREEN)); - - helpComponent = helpComponent.append(component).append(Component.newline()); - } - return helpComponent; - } -} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/package-info.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/package-info.java deleted file mode 100644 index da990c55..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@NotNullByDefault -package net.onelitefeather.cygnus.setup.command; - -import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSurvivorSpawnCommand.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSurvivorSpawnCommand.java deleted file mode 100644 index e7f5f321..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/SetupSurvivorSpawnCommand.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.onelitefeather.cygnus.setup.command.parts; - -import net.kyori.adventure.text.Component; -import net.minestom.server.command.builder.Command; -import net.minestom.server.command.builder.condition.Conditions; -import net.minestom.server.coordinate.Pos; -import net.minestom.server.entity.Player; -import net.onelitefeather.cygnus.common.map.GameMap; -import net.onelitefeather.cygnus.common.map.GameMapBuilder; -import net.onelitefeather.cygnus.setup.util.SetupData; -import net.onelitefeather.cygnus.setup.util.SetupMessages; -import net.onelitefeather.cygnus.setup.util.SetupMode; -import net.onelitefeather.cygnus.setup.util.SetupTags; - -public final class SetupSurvivorSpawnCommand extends Command { - - public SetupSurvivorSpawnCommand(SetupData setupData) { - super("survivor"); - setCondition(Conditions::playerOnly); - addSyntax((sender, context) -> { - int ordinalId = sender.getTag(SetupTags.SETUP_ID_TAG); - - if (ordinalId == -1) { - sender.sendMessage(SetupMessages.MISSING_MAP_SELECTION); - return; - } - - if (!SetupMode.isMode(SetupMode.GAME, ordinalId)) { - sender.sendMessage(SetupMessages.getInvalidModeDuringLobby("survivor")); - return; - } - - if (setupData.hasPageMode()) { - sender.sendMessage(SetupMessages.DISABLED_PAGE_MODE); - return; - } - - GameMapBuilder gameMap = (GameMapBuilder) setupData.getBaseMapBuilder(); - gameMap.addSurvivorSpawn(Pos.fromPoint(((Player) sender).getPosition())); - sender.sendMessage(Component.text("The survivor spawn was added to the map")); - }); - } -} diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/package-info.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/package-info.java deleted file mode 100644 index ba9b9db8..00000000 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/command/parts/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@NotNullByDefault -package net.onelitefeather.cygnus.setup.command.parts; - -import org.jetbrains.annotations.NotNullByDefault; \ No newline at end of file diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java index 1ea04658..ca241e5a 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/data/GameData.java @@ -27,6 +27,7 @@ public class GameData extends InstanceSetupData { private final SurvivorViewInventory survivorInventory; private GameMapBuilder gameMapBuilder; private boolean pageMode; + private boolean survivorMode; /** * Constructs a new GameData instance. @@ -42,7 +43,6 @@ public GameData(UUID uuid, MapEntry mapEntry) { throw new IllegalArgumentException("Player with UUID " + uuid + " is not online."); } - System.out.println("After loadData: " + System.identityHashCode(this.gameMapBuilder)); this.inventory = new MapDataOverviewInventory(player, this.gameMapBuilder, InventoryMode.GAME); this.survivorInventory = new SurvivorViewInventory(player, this.gameMapBuilder); } @@ -54,6 +54,8 @@ public void swapPageMode() { this.pageMode = !this.pageMode; } + public void swapSurvivorMode() { this.survivorMode = !this.survivorMode; } + /** * {@inheritDoc} */ @@ -97,6 +99,17 @@ public void setPosition(MapDataCategory category, Player player) { ((GameMapBuilder) getMapBuilder()).setSlenderSpawn(pos); triggerUpdate(InventoryTarget.GENERAL); } + case SURVIVOR -> { + Pos spawnPos = new Pos( + pos.blockX(), + pos.blockY() + 1, + pos.blockZ(), + player.getPosition().yaw(), + 0f + ); + this.gameMapBuilder.addSurvivorSpawn(spawnPos); + triggerUpdate(InventoryTarget.SURVIVOR); + } default -> {} } } @@ -121,6 +134,24 @@ public void handleItemInteraction(Player player, byte tagValue) { SetupItems.setGameLayout(player); return; } + + if (5 == tagValue) { + this.swapSurvivorMode(); + SetupItems.setSurvivorSpawn(player); + return; + } + + if (6 == tagValue) { + this.openInventory(InventoryTarget.SURVIVOR); + return; + } + + if (7 == tagValue) { + this.swapSurvivorMode(); + SetupItems.setGameLayout(player); + return; + } + super.handleItemInteraction(player, tagValue); } @@ -185,6 +216,10 @@ public boolean hasPageMode() { return pageMode; } + public boolean hasSurvivorMode() { + return this.survivorMode; + } + /** * Returns the GameMapBuilder instance used for building the game map. * diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/SurvivorViewInventory.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/SurvivorViewInventory.java index 04b1a9cd..57f95d1d 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/SurvivorViewInventory.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/inventory/view/SurvivorViewInventory.java @@ -16,7 +16,7 @@ public class SurvivorViewInventory extends PersonalInventoryBuilder { - private static final int[] SLOTS = LayoutCalculator.quad(InventoryType.CHEST_1_ROW.getSize() + 1, InventoryType.CHEST_5_ROW.getSize()); + private static final int[] SLOTS = LayoutCalculator.quad(InventoryType.CHEST_1_ROW.getSize(), InventoryType.CHEST_5_ROW.getSize() - 1); private final GameMapBuilder mapBuilder; /** @@ -35,19 +35,19 @@ public SurvivorViewInventory(Player player, GameMapBuilder mapBuilder) { setLayout(layout); this.setDataLayoutFunction(dataLayout -> { - dataLayout = dataLayout != null ? dataLayout : InventoryLayout.fromType(getType()); - - if (this.mapBuilder.getSurvivorSpawns().isEmpty()) return dataLayout; - + InventoryLayout internalLayout = dataLayout != null ? dataLayout : InventoryLayout.fromType(getType()); + if (this.mapBuilder.getSurvivorSpawns().isEmpty()) { + return internalLayout; + } Iterator iterator = mapBuilder.getSurvivorSpawns().iterator(); for (int i = 0; i < SLOTS.length && iterator.hasNext(); i++) { Pos pos = iterator.next(); - dataLayout.setItem(SLOTS[i], new PositionSlot(MapDataCategory.SPAWN, pos)); + internalLayout.setItem(SLOTS[i], new PositionSlot(MapDataCategory.SURVIVOR, pos)); } - return dataLayout; + return internalLayout; }); - + this.invalidateLayout(); register(); } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java index be921d58..fbfe7ec8 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/item/SetupItems.java @@ -26,6 +26,7 @@ public final class SetupItems { private static final HotBarLayout lobbySetupLayout; private static final HotBarLayout gameSetupLayout; private static final HotBarLayout pageLayout; + private static final HotBarLayout survivorSpawnLayout; static { DECORATION_PANE = ItemStack.builder(Material.BLACK_STAINED_GLASS_PANE).customName(Component.empty()).build(); @@ -48,24 +49,42 @@ public final class SetupItems { lobbySetupLayout.set(6, saveItem); gameSetupLayout = new HotBarLayout(); - gameSetupLayout.set(2, ItemStack.builder(Material.COMPASS) + gameSetupLayout.set(1, ItemStack.builder(Material.COMPASS) .customName(Component.text("Data", NamedTextColor.AQUA)) .set(Tags.ITEM_TAG, (byte) 0x02) .build() ); - gameSetupLayout.set(4, ItemStack.builder(Material.PAPER) + gameSetupLayout.set(3, ItemStack.builder(Material.PAPER) .customName(Component.text("Page", NamedTextColor.AQUA)) .set(Tags.ITEM_TAG, (byte) 0x03) .build() ); - gameSetupLayout.set(6, saveItem); + gameSetupLayout.set(5, ItemStack.builder(Material.MINECART) + .customName(Component.text("Survivor", NamedTextColor.YELLOW)) + .set(Tags.ITEM_TAG, (byte) 0x05) + .build() + ); + gameSetupLayout.set(7, saveItem); pageLayout = new HotBarLayout(); - pageLayout.set(2, ItemStack.builder(Material.BARRIER) + pageLayout.set(4, ItemStack.builder(Material.BARRIER) .customName(Component.text("Leave page mode", NamedTextColor.RED)) .set(Tags.ITEM_TAG, (byte) 0x04) .build() ); + + survivorSpawnLayout = new HotBarLayout(); + survivorSpawnLayout.set(2, ItemStack.builder(Material.CHEST) + .customName(Component.text("Spawns", NamedTextColor.AQUA)) + .set(Tags.ITEM_TAG, (byte) 0x06) + .build() + ); + survivorSpawnLayout.set(6 + , ItemStack.builder(Material.BARRIER) + .customName(Component.text("Leave mode", NamedTextColor.RED)) + .set(Tags.ITEM_TAG, (byte) 0x07) + .build() + ); } /** @@ -98,6 +117,16 @@ public static void setGameLayout(Player player) { player.setHeldItemSlot(FOURTH_INDEX); } + /** + * Set's the {@link ItemStack} which are required for the survivor setup. + * + * @param player who should receive the items + */ + public static void setSurvivorSpawn(Player player) { + survivorSpawnLayout.apply(player); + player.setHeldItemSlot(ZERO_INDEX); + } + /** * Set's the {@link ItemStack} which are required for the page setup. * diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SpawnCreationListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SpawnCreationListener.java new file mode 100644 index 00000000..6388d5c8 --- /dev/null +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SpawnCreationListener.java @@ -0,0 +1,38 @@ +package net.onelitefeather.cygnus.setup.listener; + +import net.minestom.server.coordinate.Pos; +import net.minestom.server.entity.Player; +import net.minestom.server.event.player.PlayerBlockBreakEvent; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import net.onelitefeather.cygnus.setup.util.SetupTags; +import net.onelitefeather.guira.SetupDataService; +import net.onelitefeather.guira.data.SetupData; + +import java.util.function.Consumer; + +public class SpawnCreationListener implements Consumer { + + private final SetupDataService setupData; + + public SpawnCreationListener(SetupDataService setupData) { + this.setupData = setupData; + } + + @Override + public void accept(PlayerBlockBreakEvent event) { + event.setCancelled(true); + + Player player = event.getPlayer(); + + if (!player.hasTag(SetupTags.SETUP_ID_TAG)) return; + + SetupData setupData = this.setupData.get(player.getUuid()).orElse(null); + + if (setupData == null) return; + + if (!(setupData instanceof GameData gameData) || !gameData.hasSurvivorMode()) return; + + gameData.setPosition(MapDataCategory.SURVIVOR, player); + } +} diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java index 743f2042..ceccf673 100644 --- a/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/item/SetupItemsTest.java @@ -48,8 +48,7 @@ void testPageItemSet(@NotNull Env env) { Player player = env.createPlayer(instance); SetupItems.setPageItems(player); - assertItem(player, 2, (byte) 0x03); - assertItem(player, 6, (byte) 0x01); + assertItem(player, 4, (byte) 0x04); env.destroyInstance(instance, true); }