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 956dac5b..e865cc29 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 @@ -143,8 +143,14 @@ public void openInventory(InventoryTarget target) { @Override public void triggerUpdate(InventoryTarget target) { switch (target) { - case GENERAL -> this.inventory.invalidateDataLayout(); - case SURVIVOR -> this.survivorInventory.invalidateDataLayout(); + case GENERAL -> { + this.inventory.invalidateDataLayout(); + this.inventory.invalidateLayout(); + } + case SURVIVOR -> { + this.survivorInventory.invalidateDataLayout(); + this.survivorInventory.invalidateLayout(); + } case PAGE -> { } } @@ -180,13 +186,7 @@ public void setPosition(MapDataCategory category, Player player) { triggerUpdate(InventoryTarget.GENERAL); } case SURVIVOR -> { - Pos spawnPos = new Pos( - pos.blockX(), - pos.blockY() + 1, - pos.blockZ(), - player.getPosition().yaw(), - 0f - ); + Pos spawnPos = new Pos(pos.x(), pos.y(), pos.z(), pos.yaw(), 0f); this.gameMapBuilder.addSurvivorSpawn(spawnPos); triggerUpdate(InventoryTarget.SURVIVOR); } @@ -204,13 +204,18 @@ public void handleItemInteraction(Player player, byte tagValue) { swapPageMode(); if (hasPageMode()) { player.sendMessage(SetupMessages.PAGE_MODE_ENABLED); - player.sendMessage(SetupMessages.PAGE_MODE_INFORM); + player.sendMessage(SetupMessages.getModeInform("page")); + SetupItems.setPageItems(player); + } else { + player.sendMessage(SetupMessages.PAGE_MODE_DISABLED); + SetupItems.setGameLayout(player); } - SetupItems.setPageItems(player); return; } if (SetupItemId.LEAVE_PAGE == tagValue) { - swapPageMode(); + if (hasPageMode()) { + swapPageMode(); + } player.sendMessage(SetupMessages.PAGE_MODE_DISABLED); SetupItems.setGameLayout(player); return; @@ -218,7 +223,14 @@ public void handleItemInteraction(Player player, byte tagValue) { if (SetupItemId.SURVIVOR == tagValue) { this.swapSurvivorMode(); - SetupItems.setSurvivorSpawn(player); + if (hasSurvivorMode()) { + player.sendMessage(SetupMessages.SURVIVOR_MODE_ENABLED); + player.sendMessage(SetupMessages.getModeInform("survivor")); + SetupItems.setSurvivorSpawn(player); + } else { + player.sendMessage(SetupMessages.SURVIVOR_MODE_DISABLED); + SetupItems.setGameLayout(player); + } return; } @@ -228,7 +240,10 @@ public void handleItemInteraction(Player player, byte tagValue) { } if (SetupItemId.LEAVE_MODE == tagValue) { - this.swapSurvivorMode(); + if (hasSurvivorMode()) { + this.swapSurvivorMode(); + } + player.sendMessage(SetupMessages.SURVIVOR_MODE_DISABLED); SetupItems.setGameLayout(player); return; } @@ -264,7 +279,8 @@ public void handleDataDelete(MapDataCategory category) { */ @Override public void handleDataContextDelete(MapDataCategory category, Point point) { - if (category == MapDataCategory.SURVIVOR && point instanceof Pos pos) { + if (category == MapDataCategory.SURVIVOR) { + Pos pos = point instanceof Pos givenPos ? givenPos : new Pos(point.x(), point.y(), point.z()); this.gameMapBuilder.removeSurvivorSpawn(pos); this.triggerUpdate(InventoryTarget.SURVIVOR); } else if (category == MapDataCategory.PAGE) { diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/AuthorInputHandler.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/AuthorInputHandler.java index c815641a..ea4e954c 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/AuthorInputHandler.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/AuthorInputHandler.java @@ -4,6 +4,7 @@ import net.kyori.adventure.nbt.FloatBinaryTag; import net.minestom.server.event.player.PlayerCustomClickEvent; import net.onelitefeather.cygnus.setup.data.InstanceSetupData; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData.InventoryTarget; import net.onelitefeather.guira.SetupDataService; public final class AuthorInputHandler implements DialogHandler { @@ -32,7 +33,8 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { setupDataService.get(event.getPlayer().getUuid()).ifPresent(data -> { InstanceSetupData instanceSetupData = (InstanceSetupData) data; instanceSetupData.getMapBuilder().builders(authors); - instanceSetupData.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); + instanceSetupData.triggerUpdate(InventoryTarget.GENERAL); + instanceSetupData.openInventory(InventoryTarget.GENERAL); }); } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java index 6d7bd57a..80dd4b87 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/DynamicDataHandler.java @@ -36,13 +36,16 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { if (category == MapDataCategory.PAGE) { point = player.getPageToDelete() != null ? player.getPageToDelete() : (player.getPageResource() != null ? player.getPageResource().position() : null); } - ((InstanceSetupData)data).handleDataContextDelete(category, point); + InstanceSetupData setupData = (InstanceSetupData) data; + setupData.handleDataContextDelete(category, point); if (category == MapDataCategory.SURVIVOR) { player.setSurvivorToDelete(null); + setupData.openInventory(InstanceSetupData.InventoryTarget.SURVIVOR); } if (category == MapDataCategory.PAGE) { player.setPageToDelete(null); player.setPageResource(null); + setupData.openInventory(InstanceSetupData.InventoryTarget.PAGE); } }); diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/MapNameHandler.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/MapNameHandler.java index 5ca0e551..a106821f 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/MapNameHandler.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/MapNameHandler.java @@ -31,6 +31,7 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { instance.getMapBuilder().name(nameEntry); instance.triggerUpdate(InstanceSetupData.InventoryTarget.GENERAL); instance.updateTitle(); + instance.openInventory(InstanceSetupData.InventoryTarget.GENERAL); }); } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/NonDynamicDataHandler.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/NonDynamicDataHandler.java index 6040145c..d5aba6eb 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/NonDynamicDataHandler.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/dialog/handler/NonDynamicDataHandler.java @@ -26,7 +26,9 @@ public void handle(PlayerCustomClickEvent event, CompoundBinaryTag payload) { MapDataCategory category = MapDataCategory.byId(categoryId); dataService.get(event.getPlayer().getUuid()).ifPresent(data -> { - ((InstanceSetupData)data).handleDataDelete(category); + InstanceSetupData setupData = (InstanceSetupData) data; + setupData.handleDataDelete(category); + setupData.openInventory(InstanceSetupData.InventoryTarget.GENERAL); }); } } 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 6196723b..209e250d 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 @@ -37,8 +37,9 @@ public SurvivorViewInventory(Player player, GameMapBuilder mapBuilder) { this.setDataLayoutFunction(dataLayout -> { InventoryLayout internalLayout = dataLayout != null ? dataLayout : InventoryLayout.fromType(getType()); + internalLayout.blank(SLOTS); + if (this.mapBuilder.getSurvivorSpawns().isEmpty()) { - internalLayout.blank(SLOTS); return internalLayout; } 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 index a1f9c975..5a3dcafd 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SpawnCreationListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/SpawnCreationListener.java @@ -1,12 +1,20 @@ package net.onelitefeather.cygnus.setup.listener; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.minestom.server.coordinate.Pos; +import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Player; import net.minestom.server.event.player.PlayerBlockBreakEvent; +import net.onelitefeather.cygnus.common.Messages; +import net.onelitefeather.cygnus.common.map.GameMapBuilder; import net.onelitefeather.cygnus.setup.data.GameData; -import net.onelitefeather.cygnus.setup.map.MapDataCategory; +import net.onelitefeather.cygnus.setup.data.InstanceSetupData; import net.onelitefeather.cygnus.setup.util.SetupTags; import net.onelitefeather.guira.SetupDataService; import net.onelitefeather.guira.data.SetupData; +import net.theevilreaper.aves.util.Components; import java.util.function.Consumer; @@ -32,6 +40,23 @@ public void accept(PlayerBlockBreakEvent event) { if (!(setupData instanceof GameData gameData) || !gameData.hasSurvivorMode()) return; - gameData.setPosition(MapDataCategory.SURVIVOR, player); + Vec blockPos = event.getBlockPosition().asVec(); + Pos spawnPos = new Pos( + blockPos.x() + 0.5, + blockPos.y() + 1.0, + blockPos.z() + 0.5, + player.getPosition().yaw(), + 0f + ); + + if (((GameMapBuilder) gameData.getMapBuilder()).addSurvivorSpawn(spawnPos)) { + gameData.triggerUpdate(InstanceSetupData.InventoryTarget.SURVIVOR); + Component component = Component.text("Created survivor spawn at: ", NamedTextColor.GRAY) + .append(Components.convertPoint(spawnPos).style(Style.style(NamedTextColor.GOLD))); + player.sendMessage(Messages.withPrefix(component)); + } else { + Component component = Component.text("Survivor spawn already exists at this block!", NamedTextColor.RED); + player.sendMessage(Messages.withPrefix(component)); + } } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java index 67b8b23a..feb8fa6a 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/dialog/DialogPayloadListener.java @@ -36,7 +36,10 @@ public void accept(PlayerCustomClickEvent event) { BinaryTag payload = event.getPayload(); if (payload == null) return; + DialogHandler handler = this.handlers.get(key); + if (handler == null) return; + CompoundBinaryTag castedPayload = (CompoundBinaryTag) payload; - this.handlers.get(key).handle(event, castedPayload); + handler.handle(event, castedPayload); } } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java index f59cd0df..bac49b1f 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListener.java @@ -30,6 +30,7 @@ public void accept(MapSetupSaveEvent event) { SetupData data = setupData.get(); data.save(); + this.dataService.remove(player.getUuid()); this.teleportBackLogic.accept(event.getPlayer()); MinecraftServer.getSchedulerManager().scheduleNextTick(data::reset); } diff --git a/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupMessages.java b/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupMessages.java index 8b8be579..e3ffaf71 100644 --- a/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupMessages.java +++ b/setup/src/main/java/net/onelitefeather/cygnus/setup/util/SetupMessages.java @@ -32,7 +32,8 @@ public final class SetupMessages { public static final Component DELETE_CLICK; public static final Component PAGE_MODE_ENABLED; public static final Component PAGE_MODE_DISABLED; - public static final Component PAGE_MODE_INFORM; + public static final Component SURVIVOR_MODE_ENABLED; + public static final Component SURVIVOR_MODE_DISABLED; static { SPACE_SEPARATOR = Component.text("ยป ", NamedTextColor.GRAY); @@ -74,7 +75,16 @@ public final class SetupMessages { .append(Component.space()) .append(Component.text("disabled", NamedTextColor.RED)) ); - PAGE_MODE_INFORM = Messages.withPrefix(Component.text("Don't forget to disable this mode", NamedTextColor.GRAY)); + SURVIVOR_MODE_ENABLED = Messages.withPrefix( + Component.text("The survivor mode has been", NamedTextColor.GRAY) + .append(Component.space()) + .append(Component.text("enabled", NamedTextColor.GREEN)) + ); + SURVIVOR_MODE_DISABLED = Messages.withPrefix( + Component.text("The survivor mode has been", NamedTextColor.GRAY) + .append(Component.space()) + .append(Component.text("disabled", NamedTextColor.RED)) + ); } private SetupMessages() { @@ -94,6 +104,19 @@ private SetupMessages() { return Messages.withMini("You are looking in an invalid direction! ()", faceTag); } + /** + * Creates a new {@link Component} instance which informs the player to disable the given mode. + * + * @param mode which should be displayed + * @return the created component + */ + @Contract(value = "_ -> new", pure = true) + public static @NotNull Component getModeInform(@NotNull String mode) { + PreProcess modePreProcess = Tag.preProcessParsed(mode); + TagResolver modeTag = TagResolver.builder().tag("mode", (_, _) -> modePreProcess).build(); + return Messages.withMiniPrefix("Don't forget to disable mode", modeTag); + } + /** * Returns a list that contains the given components which some additional empty components * diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java index ec103039..bb242f0f 100644 --- a/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/data/GameDataTest.java @@ -1,18 +1,24 @@ package net.onelitefeather.cygnus.setup.data; +import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Player; import net.minestom.server.instance.Instance; import net.minestom.server.utils.Direction; import net.minestom.testing.Env; import net.minestom.testing.extension.MicrotusExtension; +import net.onelitefeather.cygnus.common.map.GameMap; +import net.onelitefeather.cygnus.setup.map.MapDataCategory; import net.theevilreaper.aves.map.MapEntry; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import java.nio.file.Paths; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; @ExtendWith(MicrotusExtension.class) class GameDataTest { @@ -43,4 +49,64 @@ void testAddAndRemovePage(Env env) { env.destroyInstance(instance, true); } + + @Test + void testSwapSurvivorMode(Env env) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(Paths.get("")); + + GameData gameData = new GameData(player, mapEntry); + + assertFalse(gameData.hasSurvivorMode()); + gameData.swapSurvivorMode(); + assertTrue(gameData.hasSurvivorMode()); + gameData.swapSurvivorMode(); + assertFalse(gameData.hasSurvivorMode()); + + env.destroyInstance(instance, true); + } + + @Test + void testSetSurvivorPosition(Env env) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(Paths.get("")); + + GameData gameData = new GameData(player, mapEntry); + + Pos playerPosLookingDown = new Pos(10.5, 64.0, -15.5, 90.0f, 45.0f); + player.teleport(playerPosLookingDown); + + gameData.setPosition(MapDataCategory.SURVIVOR, player); + GameMap map = (GameMap) gameData.getMapBuilder().build(); + + Pos expectedSpawn = new Pos(10.5, 64.0, -15.5, 90.0f, 0.0f); + assertEquals(1, map.getSurvivorSpawns().size()); + assertTrue(map.getSurvivorSpawns().contains(expectedSpawn)); + + env.destroyInstance(instance, true); + } + + @Test + void testRemoveSurvivorPosition(Env env) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(Paths.get("")); + + GameData gameData = new GameData(player, mapEntry); + + Pos playerPos = new Pos(10.5, 64.0, -15.5, 90.0f, 0.0f); + player.teleport(playerPos); + + gameData.setPosition(MapDataCategory.SURVIVOR, player); + GameMap mapWithSpawn = (GameMap) gameData.getMapBuilder().build(); + assertEquals(1, mapWithSpawn.getSurvivorSpawns().size()); + + gameData.handleDataContextDelete(MapDataCategory.SURVIVOR, playerPos); + GameMap mapAfterDelete = (GameMap) gameData.getMapBuilder().build(); + assertEquals(0, mapAfterDelete.getSurvivorSpawns().size()); + + env.destroyInstance(instance, true); + } } diff --git a/setup/src/test/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListenerTest.java b/setup/src/test/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListenerTest.java new file mode 100644 index 00000000..63cb31c8 --- /dev/null +++ b/setup/src/test/java/net/onelitefeather/cygnus/setup/listener/map/MapSetupSaveListenerTest.java @@ -0,0 +1,42 @@ +package net.onelitefeather.cygnus.setup.listener.map; + +import net.minestom.server.entity.Player; +import net.minestom.server.instance.Instance; +import net.minestom.testing.Env; +import net.minestom.testing.extension.MicrotusExtension; +import net.onelitefeather.cygnus.setup.data.GameData; +import net.onelitefeather.cygnus.setup.event.MapSetupSaveEvent; +import net.onelitefeather.guira.SetupDataService; +import net.theevilreaper.aves.map.MapEntry; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@ExtendWith(MicrotusExtension.class) +class MapSetupSaveListenerTest { + + @Test + void testSaveRemovesDataFromDataService(Env env, @TempDir Path tempDir) { + Instance instance = env.createFlatInstance(); + Player player = env.createPlayer(instance); + MapEntry mapEntry = MapEntry.of(tempDir); + + SetupDataService dataService = SetupDataService.create(); + GameData gameData = new GameData(player, mapEntry); + dataService.add(player.getUuid(), gameData); + + assertTrue(dataService.get(player.getUuid()).isPresent()); + + MapSetupSaveListener listener = new MapSetupSaveListener(dataService, p -> {}); + listener.accept(new MapSetupSaveEvent(player)); + + assertFalse(dataService.get(player.getUuid()).isPresent(), "Data should be removed from dataService on save"); + + env.destroyInstance(instance, true); + } +}