From 4c368ec71456af6de058c7607fb2c730e3bec2e4 Mon Sep 17 00:00:00 2001 From: FireInstall Date: Tue, 12 Nov 2024 23:28:39 +0100 Subject: [PATCH] Better entity data handling: - This allows to reset entities to nbt states before the minigame had started (but recording changes is not implemented yet) - enables SpawnEntityAction to finally work properly To make the changes above possible, I changed how MenuItems accept user input. Now it will only close, if the user inputs the right data and ignore everything else. Update gradle --- .../java/au/com/mineauz/minigames/Events.java | 28 +- .../minigames/config/MaterialFlag.java | 3 +- .../language/MinigamePlaceHolderKey.java | 1 + .../com/mineauz/minigames/menu/MenuItem.java | 4 - .../minigames/menu/MenuItemAddFlag.java | 9 +- .../minigames/menu/MenuItemAddTeam.java | 5 +- .../menu/MenuItemAddWhitelistBlock.java | 57 +- .../minigames/menu/MenuItemBlockData.java | 28 +- .../minigames/menu/MenuItemComponent.java | 9 +- .../minigames/menu/MenuItemDecimal.java | 5 +- .../menu/MenuItemDisplayLoadout.java | 7 +- .../minigames/menu/MenuItemInteger.java | 13 +- .../mineauz/minigames/menu/MenuItemList.java | 7 +- .../minigames/menu/MenuItemLoadoutAdd.java | 15 +- .../mineauz/minigames/menu/MenuItemLong.java | 13 +- .../minigames/menu/MenuItemRewardGroup.java | 7 +- .../menu/MenuItemRewardGroupAdd.java | 15 +- .../menu/MenuItemStatusEffectAdd.java | 9 +- .../minigames/menu/MenuItemString.java | 9 +- .../mineauz/minigames/menu/MenuItemTime.java | 10 +- .../menu/consumer/BlockDataConsumer.java | 8 + .../menu/consumer/EntityConsumer.java | 8 + .../menu/consumer/MaterialConsumer.java | 8 + .../menu/consumer/StringConsumer.java | 7 + .../minigames/menu/consumer/package-info.java | 7 + .../minigame/modules/ResourcePackModule.java | 12 +- .../minigames/recorder/BasicRecorder.java | 14 +- .../minigames/recorder/EntityData.java | 28 +- .../minigames/recorder/RecorderData.java | 50 +- .../minigames/recorder/RegenRecorder.java | 20 +- .../actions/SpawnEntityAction.java | 522 +++--------------- .../config/EntitySnapshotFlag.java | 61 ++ .../language/RegionLangKey.java | 2 + .../menu/MenuItemSelectEntity.java | 127 +++++ .../resources/minigames-regions.properties | 2 + gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +- gradlew.bat | 22 +- 39 files changed, 537 insertions(+), 624 deletions(-) create mode 100644 Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/BlockDataConsumer.java create mode 100644 Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/EntityConsumer.java create mode 100644 Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/MaterialConsumer.java create mode 100644 Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/StringConsumer.java create mode 100644 Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/package-info.java create mode 100644 Regions/src/main/java/au/com/mineauz/minigamesregions/config/EntitySnapshotFlag.java create mode 100644 Regions/src/main/java/au/com/mineauz/minigamesregions/menu/MenuItemSelectEntity.java diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/Events.java b/Minigames/src/main/java/au/com/mineauz/minigames/Events.java index da5fb651c..503004e60 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/Events.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/Events.java @@ -9,6 +9,9 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMiscLangKey; import au.com.mineauz.minigames.menu.MenuItem; +import au.com.mineauz.minigames.menu.consumer.BlockDataConsumer; +import au.com.mineauz.minigames.menu.consumer.EntityConsumer; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.Minigame; import au.com.mineauz.minigames.minigame.MinigameState; import au.com.mineauz.minigames.minigame.Team; @@ -258,19 +261,34 @@ private void onPlayerConnect(final @NotNull PlayerJoinEvent event) { } @EventHandler - public void playerInteract(@NotNull PlayerInteractEvent event) { + private void player(@NotNull EntityDamageByEntityEvent event) { + if (event.getDamager() instanceof Player player) { + final MinigamePlayer mgPlayer = pdata.getMinigamePlayer(player); + + if (mgPlayer.isInMenu() && mgPlayer.getNoClose() && mgPlayer.getManualEntry() instanceof EntityConsumer entityConsumer) { + event.setCancelled(true); + mgPlayer.setNoClose(false); + mgPlayer.setNoClose(false); + entityConsumer.acceptEntity(event.getEntity()); + mgPlayer.setManualEntry(null); + } + } + } + + @EventHandler + private void playerInteract(@NotNull PlayerInteractEvent event) { MinigamePlayer mgPlayer = pdata.getMinigamePlayer(event.getPlayer()); if (mgPlayer.isInMinigame() && !mgPlayer.canInteract()) { event.setCancelled(true); return; } - if (mgPlayer.isInMenu() && mgPlayer.getNoClose() && mgPlayer.getManualEntry() != null) { + if (mgPlayer.isInMenu() && mgPlayer.getNoClose() && mgPlayer.getManualEntry() instanceof BlockDataConsumer blockDataConsumer) { event.setCancelled(true); mgPlayer.setNoClose(false); if (event.getClickedBlock() != null) { mgPlayer.setNoClose(false); - mgPlayer.getManualEntry().checkValidEntry(event.getClickedBlock().getBlockData().getAsString()); + blockDataConsumer.acceptBlockData(event.getClickedBlock().getBlockData()); mgPlayer.setManualEntry(null); } return; @@ -742,10 +760,10 @@ private void closeMenu(@NotNull InventoryCloseEvent event) { @EventHandler private void manualItemEntry(@NotNull AsyncPlayerChatEvent event) { MinigamePlayer mgPlayer = pdata.getMinigamePlayer(event.getPlayer()); - if (mgPlayer.isInMenu() && mgPlayer.getNoClose() && mgPlayer.getManualEntry() != null) { + if (mgPlayer.isInMenu() && mgPlayer.getNoClose() && mgPlayer.getManualEntry() instanceof StringConsumer stringAcceptor) { event.setCancelled(true); mgPlayer.setNoClose(false); - mgPlayer.getManualEntry().checkValidEntry(event.getMessage()); + stringAcceptor.acceptString(event.getMessage()); mgPlayer.setManualEntry(null); } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/config/MaterialFlag.java b/Minigames/src/main/java/au/com/mineauz/minigames/config/MaterialFlag.java index 795e3430f..f6424031f 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/config/MaterialFlag.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/config/MaterialFlag.java @@ -2,7 +2,6 @@ import au.com.mineauz.minigames.Minigames; import au.com.mineauz.minigames.menu.Callback; -import au.com.mineauz.minigames.menu.MenuItem; import au.com.mineauz.minigames.menu.MenuItemMaterial; import net.kyori.adventure.text.Component; import org.bukkit.Material; @@ -52,7 +51,7 @@ public void loadValue(@NotNull Configuration config, @NotNull String path) { @Deprecated @Override - public @NotNull MenuItem getMenuItem(@Nullable Material displayMat, @Nullable Component name) { + public @NotNull MenuItemMaterial getMenuItem(@Nullable Material displayMat, @Nullable Component name) { return getMenuItem(displayMat, name, null); } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/managers/language/MinigamePlaceHolderKey.java b/Minigames/src/main/java/au/com/mineauz/minigames/managers/language/MinigamePlaceHolderKey.java index f92fa82a8..e64f2e2ef 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/managers/language/MinigamePlaceHolderKey.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/managers/language/MinigamePlaceHolderKey.java @@ -3,6 +3,7 @@ import org.intellij.lang.annotations.Subst; public enum MinigamePlaceHolderKey implements PlaceHolderKey { + ENTITY("entity"), BIOME("biome"), COMMAND("command"), COORDINATE_X("x"), diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItem.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItem.java index 42df55c57..8d707027d 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItem.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItem.java @@ -270,10 +270,6 @@ public ItemStack onDoubleClick() { return getDisplayItem(); } - public void checkValidEntry(String entry) { - //Do Stuff - } - public @Nullable Menu getContainer() { return container; } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddFlag.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddFlag.java index cbe27d325..d1aa9eca0 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddFlag.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddFlag.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.Minigame; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; @@ -18,7 +19,7 @@ import java.time.Duration; import java.util.List; -public class MenuItemAddFlag extends MenuItem { +public class MenuItemAddFlag extends MenuItem implements StringConsumer { private final @NotNull Minigame mgm; public MenuItemAddFlag(@Nullable Material displayMat, @NotNull MinigameLangKey langKey, @NotNull Minigame mgm) { @@ -54,9 +55,9 @@ public MenuItemAddFlag(@Nullable Material displayMat, @Nullable Component name, } @Override - public void checkValidEntry(@NotNull String entry) { - mgm.addSinglePlayerFlag(entry); - getContainer().addItem(new MenuItemFlag(Material.OAK_SIGN, entry, mgm.getSinglePlayerFlags())); + public void acceptString(@NotNull String string) { + mgm.addSinglePlayerFlag(string); + getContainer().addItem(new MenuItemFlag(Material.OAK_SIGN, string, mgm.getSinglePlayerFlags())); getContainer().cancelReopenTimer(); getContainer().displayMenu(getContainer().getViewer()); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddTeam.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddTeam.java index 2bb539a57..de0010071 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddTeam.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddTeam.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMiscLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.Team; import au.com.mineauz.minigames.minigame.TeamColor; import au.com.mineauz.minigames.minigame.modules.TeamsModule; @@ -20,7 +21,7 @@ import java.util.ArrayList; import java.util.List; -public class MenuItemAddTeam extends MenuItem { +public class MenuItemAddTeam extends MenuItem implements StringConsumer { private final @NotNull TeamsModule tm; public MenuItemAddTeam(@NotNull Component name, @NotNull TeamsModule tm) { @@ -49,7 +50,7 @@ public MenuItemAddTeam(@NotNull MinigameLangKey name, @NotNull TeamsModule tm) { @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String entry) { TeamColor col = TeamColor.matchColor(entry.toUpperCase().replace(" ", "_")); if (col != null) { if (!tm.hasTeam(col)) { diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddWhitelistBlock.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddWhitelistBlock.java index ec46b5ef3..50764fc4d 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddWhitelistBlock.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemAddWhitelistBlock.java @@ -7,11 +7,14 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgCommandLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.BlockDataConsumer; +import au.com.mineauz.minigames.menu.consumer.MaterialConsumer; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; -import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.data.BlockData; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -19,7 +22,7 @@ import java.time.Duration; import java.util.List; -public class MenuItemAddWhitelistBlock extends MenuItem { +public class MenuItemAddWhitelistBlock extends MenuItem implements StringConsumer, BlockDataConsumer, MaterialConsumer { protected final @NotNull List<@NotNull Material> whitelist; public MenuItemAddWhitelistBlock(@NotNull MinigameLangKey langKey, @NotNull List<@NotNull Material> whitelist) { @@ -58,35 +61,41 @@ public MenuItemAddWhitelistBlock(@NotNull Component name, @NotNull List<@NotNull } @Override - public void checkValidEntry(@NotNull String entry) { - // try a direct match in case of a chat input - Material mat = Material.matchMaterial(entry); - - if (mat == null) { - // didn't work, now try the input as a block data, as we get when a block was clicked - try { - mat = Bukkit.createBlockData(entry).getMaterial(); - } catch (IllegalArgumentException ignored) { - } - } + public void acceptBlockData(@NotNull BlockData data) { + acceptMaterial(data.getMaterial()); + } + + @Override + public void acceptString(@NotNull String string) { + final @Nullable Material mat = Material.matchMaterial(string); if (mat != null) { - if (!whitelist.contains(mat)) { - // intern - whitelist.add(mat); - - // visual - getContainer().addItem(new MenuItemWhitelistBlock(mat, whitelist)); - } else { - MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgMenuLangKey.MENU_WHITELIST_ERROR_CONTAINS); - } + acceptMaterial(mat); } else { - // still didn't work. + // didn't work. getContainer().cancelReopenTimer(); getContainer().displayMenu(getContainer().getViewer()); MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgCommandLangKey.COMMAND_ERROR_NOTMATERIAL, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); + + /* cancel automatic reopening and reopen {@link MenuItemDisplayWhitelist}*/ + getContainer().cancelReopenTimer(); + getContainer().displayMenu(getContainer().getViewer()); + } + + } + + @Override + public void acceptMaterial(@NotNull Material mat) { + if (!whitelist.contains(mat)) { + // intern + whitelist.add(mat); + + // visual + getContainer().addItem(new MenuItemWhitelistBlock(mat, whitelist)); + } else { + MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgMenuLangKey.MENU_WHITELIST_ERROR_CONTAINS); } /* cancel automatic reopening and reopen {@link MenuItemDisplayWhitelist}*/ diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemBlockData.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemBlockData.java index ea6a57e38..603d9655c 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemBlockData.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemBlockData.java @@ -5,6 +5,8 @@ import au.com.mineauz.minigames.managers.language.MinigameMessageType; import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; +import au.com.mineauz.minigames.menu.consumer.BlockDataConsumer; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -21,7 +23,7 @@ import java.util.ArrayList; import java.util.List; -public class MenuItemBlockData extends MenuItem { +public class MenuItemBlockData extends MenuItem implements BlockDataConsumer, StringConsumer { private static final @NotNull String DESCRIPTION_TOKEN = "BlockData_description"; private final @NotNull Callback dataCallback; @@ -103,20 +105,24 @@ public void update() { } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String string) { try { - BlockData d = Bukkit.createBlockData(entry); - dataCallback.setValue(d); - setDescriptionPart(DESCRIPTION_TOKEN, createDescription(dataCallback.getValue())); - - // update the display item - if (d.getMaterial().isItem()) { - ItemStack stackUpdate = getDisplayItem(); - setDisplayItem(stackUpdate.withType(d.getMaterial())); - } + acceptBlockData(Bukkit.createBlockData(string)); } catch (IllegalArgumentException e) { MinigameMessageManager.sendMessage(getContainer().getViewer(), MinigameMessageType.ERROR, Component.text(e.getLocalizedMessage())); } + } + + @Override + public void acceptBlockData(@NotNull BlockData blockData) { + dataCallback.setValue(blockData); + setDescriptionPart(DESCRIPTION_TOKEN, createDescription(dataCallback.getValue())); + + // update the display item + if (blockData.getMaterial().isItem()) { + ItemStack stackUpdate = getDisplayItem(); + setDisplayItem(stackUpdate.withType(blockData.getMaterial())); + } getContainer().cancelReopenTimer(); getContainer().displayMenu(getContainer().getViewer()); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemComponent.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemComponent.java index b5e8a683c..9620d1194 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemComponent.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemComponent.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; @@ -18,7 +19,7 @@ import java.time.Duration; import java.util.List; -public class MenuItemComponent extends MenuItem { +public class MenuItemComponent extends MenuItem implements StringConsumer { private final static String DESCRIPTION_VALUE_TOKEN = "COMPONENT_VALUE_DESCRIPTION"; private final MiniMessage miniMessage = MiniMessage.miniMessage(); private final @NotNull Callback component; @@ -80,11 +81,11 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { - if (entry.equals("null") && allowNull) { + public void acceptString(@NotNull String string) { + if (string.equals("null") && allowNull) { component.setValue(null); } else { - component.setValue(miniMessage.deserialize(entry)); + component.setValue(miniMessage.deserialize(string)); } updateDescription(); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDecimal.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDecimal.java index 7aa8a6c58..f9e0d6c4a 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDecimal.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDecimal.java @@ -7,6 +7,7 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgCommandLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -21,7 +22,7 @@ import java.util.List; import java.util.regex.Pattern; -public class MenuItemDecimal extends MenuItem { +public class MenuItemDecimal extends MenuItem implements StringConsumer { private final static String DESCRIPTION_TOKEN = "Decimal_description"; private final static Pattern DOUBLE_PATTERN = Pattern.compile("[+-]?[0-9]+(.[0-9]+)?"); @@ -144,7 +145,7 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String entry) { if (DOUBLE_PATTERN.matcher(entry).matches()) { double entryValue = Double.parseDouble(entry); if ((min == null || entryValue >= min) && (max == null || entryValue <= max)) { diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDisplayLoadout.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDisplayLoadout.java index 059f1f547..644a32b37 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDisplayLoadout.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemDisplayLoadout.java @@ -7,6 +7,7 @@ import au.com.mineauz.minigames.managers.language.MinigameMessageType; import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.Minigame; import au.com.mineauz.minigames.minigame.TeamColor; import au.com.mineauz.minigames.minigame.modules.LoadoutModule; @@ -23,7 +24,7 @@ import java.util.ArrayList; import java.util.List; -public class MenuItemDisplayLoadout extends MenuItem { +public class MenuItemDisplayLoadout extends MenuItem implements StringConsumer { private final @NotNull PlayerLoadout loadout; private @Nullable Minigame minigame = null; private boolean allowDelete = true; @@ -179,10 +180,10 @@ public MenuItemDisplayLoadout(@Nullable Material displayMat, @Nullable Component } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String string) { String loadoutName = loadout.getName(); - if (entry.equalsIgnoreCase("yes")) { + if (string.equalsIgnoreCase("yes")) { if (minigame != null) { LoadoutModule.getMinigameModule(minigame).deleteLoadout(loadoutName); } else { diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemInteger.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemInteger.java index 70277cf5a..cdc7737e5 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemInteger.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemInteger.java @@ -7,6 +7,7 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgCommandLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -19,9 +20,11 @@ import java.time.Duration; import java.util.List; import java.util.Objects; +import java.util.regex.Pattern; -public class MenuItemInteger extends MenuItem { +public class MenuItemInteger extends MenuItem implements StringConsumer { private final static String DESCRIPTION_TOKEN = "Integer_description"; + protected final static @NotNull Pattern INT_PATTERN = Pattern.compile("-?[0-9]+"); private final @NotNull Callback value; private final @Nullable Integer min; // inclusive private final @Nullable Integer max; // inclusive @@ -146,9 +149,9 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { - if (entry.matches("-?[0-9]+")) { - int entryValue = Integer.parseInt(entry); + public void acceptString(@NotNull String string) { + if (INT_PATTERN.matcher(string).matches()) { + int entryValue = Integer.parseInt(string); if ((min == null || entryValue >= min) && (max == null || entryValue <= max)) { value.setValue(entryValue); updateDescription(); @@ -162,7 +165,7 @@ public void checkValidEntry(@NotNull String entry) { } else { MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgCommandLangKey.COMMAND_ERROR_NOTNUMBER, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); } getContainer().cancelReopenTimer(); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemList.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemList.java index 5f16495df..917b91633 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemList.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemList.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -19,7 +20,7 @@ import java.util.ArrayList; import java.util.List; -public class MenuItemList extends MenuItem { //todo add constructor with map T -> Component for display +public class MenuItemList extends MenuItem implements StringConsumer { //todo add constructor with map T -> Component for display private final static @NotNull String DESCRIPTION_TOKEN = "List_description"; private final @NotNull Callback value; private final @NotNull List options; @@ -139,9 +140,9 @@ public void updateDescription() { } @Override - public void checkValidEntry(String entry) { + public void acceptString(@NotNull String string) { for (T opt : options) { - if (opt.toString().equalsIgnoreCase(entry)) { + if (opt.toString().equalsIgnoreCase(string)) { value.setValue(opt); updateDescription(); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLoadoutAdd.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLoadoutAdd.java index 6c984196b..13cabd13a 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLoadoutAdd.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLoadoutAdd.java @@ -7,6 +7,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.Minigame; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; @@ -20,7 +21,7 @@ import java.util.List; import java.util.Map; -public class MenuItemLoadoutAdd extends MenuItem { +public class MenuItemLoadoutAdd extends MenuItem implements StringConsumer { private final @NotNull Map<@NotNull String, @NotNull PlayerLoadout> loadouts; private @Nullable Minigame minigame = null; @@ -80,13 +81,13 @@ public MenuItemLoadoutAdd(@Nullable Material displayMat, @NotNull MgMenuLangKey } @Override - public void checkValidEntry(String entry) { - entry = entry.replace(" ", "_"); - if (!loadouts.containsKey(entry)) { + public void acceptString(String string) { + string = string.replace(" ", "_"); + if (!loadouts.containsKey(string)) { for (int i = 0; i < 45; i++) { if (!getContainer().hasMenuItem(i)) { - PlayerLoadout loadout = new PlayerLoadout(entry); - loadouts.put(entry, loadout); + PlayerLoadout loadout = new PlayerLoadout(string); + loadouts.put(string, loadout); List des = MinigameMessageManager.getMgMessageList(MgMenuLangKey.MENU_DELETE_SHIFTRIGHTCLICK); if (minigame != null) { @@ -105,7 +106,7 @@ public void checkValidEntry(String entry) { getContainer().displayMenu(getContainer().getViewer()); MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgMenuLangKey.MENU_LOADOUT_ERROR_ALREADYEXISTS, - Placeholder.unparsed(MinigamePlaceHolderKey.LOADOUT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.LOADOUT.getKey(), string)); } } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLong.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLong.java index 17a51bb12..18f819ba7 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLong.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemLong.java @@ -7,6 +7,7 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgCommandLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -19,8 +20,10 @@ import java.time.Duration; import java.util.List; import java.util.Objects; +import java.util.regex.Pattern; -public class MenuItemLong extends MenuItem { +public class MenuItemLong extends MenuItem implements StringConsumer { + protected static final @NotNull Pattern LONG_PATTERN = Pattern.compile("-?[0-9]+"); private final static String DESCRIPTION_TOKEN = "Long_description"; protected final @NotNull Callback value; protected final @Nullable Long min; @@ -143,9 +146,9 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { - if (entry.matches("-?[0-9]+")) { - long entryValue = Long.parseLong(entry); + public void acceptString(@NotNull String string) { + if (LONG_PATTERN.matcher(string).matches()) { + long entryValue = Long.parseLong(string); if ((min == null || entryValue >= min) && (max == null || entryValue <= max)) { value.setValue(entryValue); updateDescription(); @@ -159,7 +162,7 @@ public void checkValidEntry(@NotNull String entry) { MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgCommandLangKey.COMMAND_ERROR_NOTNUMBER, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); } } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroup.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroup.java index 6cacf9910..8100bc393 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroup.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroup.java @@ -5,6 +5,7 @@ import au.com.mineauz.minigames.managers.language.MinigameMessageType; import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.reward.ARewardType; import au.com.mineauz.minigames.minigame.reward.RewardGroup; import au.com.mineauz.minigames.minigame.reward.RewardRarity; @@ -22,7 +23,7 @@ import java.util.ArrayList; import java.util.List; -public class MenuItemRewardGroup extends MenuItem { +public class MenuItemRewardGroup extends MenuItem implements StringConsumer { private final static String DESCRIPTION_TOKEN = "RewardGroup_description"; private final static @NotNull List<@NotNull RewardRarity> options = List.of(RewardRarity.values()); private final @NotNull RewardGroup group; @@ -95,10 +96,10 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String string) { getContainer().cancelReopenTimer(); - if (entry.equalsIgnoreCase("yes")) { // todo? + if (string.equalsIgnoreCase("yes")) { // todo? rewards.removeGroup(group); getContainer().removeItem(this.getSlot()); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroupAdd.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroupAdd.java index 7bb7e5bf3..57e3032d9 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroupAdd.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemRewardGroupAdd.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.minigame.reward.RewardGroup; import au.com.mineauz.minigames.minigame.reward.RewardRarity; import au.com.mineauz.minigames.minigame.reward.Rewards; @@ -20,7 +21,7 @@ import java.time.Duration; import java.util.List; -public class MenuItemRewardGroupAdd extends MenuItem { +public class MenuItemRewardGroupAdd extends MenuItem implements StringConsumer { private final @NotNull Rewards rewards; public MenuItemRewardGroupAdd(@Nullable Material displayMat, @NotNull MinigameLangKey langKey, @NotNull Rewards rewards) { @@ -54,25 +55,25 @@ public MenuItemRewardGroupAdd(@Nullable Material displayMat, @Nullable Component } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String string) { getContainer().cancelReopenTimer(); - entry = entry.replace(" ", "_"); + string = string.replace(" ", "_"); for (RewardGroup group : rewards.getGroups()) { - if (group.getName().equals(entry)) { + if (group.getName().equals(string)) { MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgMenuLangKey.MENU_REWARD_ERROR_GROUPEXISTS, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); getContainer().displayMenu(getContainer().getViewer()); return; } } - RewardGroup group = rewards.addGroup(entry, RewardRarity.NORMAL); + RewardGroup group = rewards.addGroup(string, RewardRarity.NORMAL); MenuItemRewardGroup mrg = new MenuItemRewardGroup(Material.CHEST, MinigameMessageManager.getMgMessage(MgMenuLangKey.MENU_REWARD_GROUP_NAME, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)), group, rewards); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)), group, rewards); getContainer().addItem(mrg); getContainer().displayMenu(getContainer().getViewer()); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemStatusEffectAdd.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemStatusEffectAdd.java index ba120ba01..1c34243f5 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemStatusEffectAdd.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemStatusEffectAdd.java @@ -8,6 +8,7 @@ import au.com.mineauz.minigames.managers.language.langkeys.MgCommandLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; @@ -24,8 +25,10 @@ import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.regex.Pattern; -public class MenuItemStatusEffectAdd extends MenuItem { +public class MenuItemStatusEffectAdd extends MenuItem implements StringConsumer { + private final static @NotNull Pattern POSITIV_INT_PATTERN = Pattern.compile("[+]?[0-9]+"); private final @NotNull PlayerLoadout loadout; public MenuItemStatusEffectAdd(@Nullable Material displayMat, @NotNull MinigameLangKey langKey, @NotNull PlayerLoadout loadout) { @@ -61,13 +64,13 @@ public MenuItemStatusEffectAdd(@Nullable Material displayMat, @Nullable Componen } @Override - public void checkValidEntry(@NotNull String entry) { + public void acceptString(@NotNull String entry) { String[] split = entry.split(", "); if (split.length == 3) { String effect = split[0].toUpperCase(); @Nullable PotionEffectType eff = Registry.EFFECT.get(NamespacedKey.fromString(effect)); if (eff != null) { - if (split[1].matches("[+]?[0-9]+") && Integer.parseInt(split[1]) != 0) { + if (POSITIV_INT_PATTERN.matcher(split[1]).matches() && Integer.parseInt(split[1]) != 0) { int level = Integer.parseInt(split[1]) - 1; Long dur = split[2].equalsIgnoreCase("inf") ? Long.valueOf(-1L) : MinigameUtils.parsePeriod(split[2]); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemString.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemString.java index c5ec0ad81..35d347fa7 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemString.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemString.java @@ -6,6 +6,7 @@ import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; import au.com.mineauz.minigames.managers.language.langkeys.MgMenuLangKey; import au.com.mineauz.minigames.managers.language.langkeys.MinigameLangKey; +import au.com.mineauz.minigames.menu.consumer.StringConsumer; import au.com.mineauz.minigames.objects.MinigamePlayer; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; @@ -18,7 +19,7 @@ import java.time.Duration; import java.util.List; -public class MenuItemString extends MenuItem { +public class MenuItemString extends MenuItem implements StringConsumer { private final static String DESCRIPTION_TOKEN = "String_description"; private final @NotNull Callback stringCallback; private boolean allowNull = false; @@ -84,11 +85,11 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { - if (entry.equals("null") && allowNull) { + public void acceptString(@NotNull String string) { + if (string.equals("null") && allowNull) { stringCallback.setValue(null); } else { - stringCallback.setValue(entry); + stringCallback.setValue(string); } updateDescription(); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemTime.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemTime.java index bd36b5251..f2a3b69d6 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemTime.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/MenuItemTime.java @@ -41,11 +41,11 @@ public void updateDescription() { } @Override - public void checkValidEntry(@NotNull String entry) { - MinigameUtils.parsePeriod(entry); + public void acceptString(@NotNull String string) { + MinigameUtils.parsePeriod(string); - if (entry.matches("-?[0-9]+")) { - long entryValue = Long.parseLong(entry); + if (LONG_PATTERN.matcher(string).matches()) { + long entryValue = Long.parseLong(string); if ((min == null || entryValue >= min) && (max == null || entryValue <= max)) { value.setValue(entryValue); updateDescription(); @@ -59,7 +59,7 @@ public void checkValidEntry(@NotNull String entry) { MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgCommandLangKey.COMMAND_ERROR_NOTNUMBER, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); } } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/BlockDataConsumer.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/BlockDataConsumer.java new file mode 100644 index 000000000..ba94329f1 --- /dev/null +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/BlockDataConsumer.java @@ -0,0 +1,8 @@ +package au.com.mineauz.minigames.menu.consumer; + +import org.bukkit.block.data.BlockData; +import org.jetbrains.annotations.NotNull; + +public interface BlockDataConsumer { + void acceptBlockData(@NotNull BlockData blockData); +} diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/EntityConsumer.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/EntityConsumer.java new file mode 100644 index 000000000..5006d1977 --- /dev/null +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/EntityConsumer.java @@ -0,0 +1,8 @@ +package au.com.mineauz.minigames.menu.consumer; + +import org.bukkit.entity.Entity; +import org.jetbrains.annotations.NotNull; + +public interface EntityConsumer { + void acceptEntity(@NotNull Entity entity); +} diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/MaterialConsumer.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/MaterialConsumer.java new file mode 100644 index 000000000..c471d1561 --- /dev/null +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/MaterialConsumer.java @@ -0,0 +1,8 @@ +package au.com.mineauz.minigames.menu.consumer; + +import org.bukkit.Material; +import org.jetbrains.annotations.NotNull; + +public interface MaterialConsumer { + void acceptMaterial(@NotNull Material material); +} diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/StringConsumer.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/StringConsumer.java new file mode 100644 index 000000000..e9cdf6097 --- /dev/null +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/StringConsumer.java @@ -0,0 +1,7 @@ +package au.com.mineauz.minigames.menu.consumer; + +import org.jetbrains.annotations.NotNull; + +public interface StringConsumer { + void acceptString(@NotNull String string); +} diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/package-info.java b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/package-info.java new file mode 100644 index 000000000..71b8f1c2d --- /dev/null +++ b/Minigames/src/main/java/au/com/mineauz/minigames/menu/consumer/package-info.java @@ -0,0 +1,7 @@ +/** + * This package contains interfaces that guarantee the implementing class has + * a function accepting a parameter with a specific type. + * This may be parallel to {@link java.util.function.Consumer}, + * but the classes here don't work with generics and therefor can work with {@code instanceof}. + */ +package au.com.mineauz.minigames.menu.consumer; \ No newline at end of file diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/minigame/modules/ResourcePackModule.java b/Minigames/src/main/java/au/com/mineauz/minigames/minigame/modules/ResourcePackModule.java index 871f490e2..76ce53f5b 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/minigame/modules/ResourcePackModule.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/minigame/modules/ResourcePackModule.java @@ -95,20 +95,20 @@ public void setValue(@NotNull Component value) { } }) { @Override - public void checkValidEntry(@NotNull String entry) { - if (entry.isEmpty()) { - super.checkValidEntry(entry); + public void acceptString(@NotNull String string) { + if (string.isEmpty()) { + super.acceptString(string); return; } - ResourcePack pack = Minigames.getPlugin().getResourceManager().getResourcePack(entry); + ResourcePack pack = Minigames.getPlugin().getResourceManager().getResourcePack(string); if (pack == null) { getContainer().cancelReopenTimer(); getContainer().displayMenu(getContainer().getViewer()); MinigameMessageManager.sendMgMessage(getContainer().getViewer(), MinigameMessageType.ERROR, MgMiscLangKey.MINIGAME_RESSOURCEPACK_NORESSOURCEPACK, - Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), entry)); + Placeholder.unparsed(MinigamePlaceHolderKey.TEXT.getKey(), string)); } else { - super.checkValidEntry(entry); + super.acceptString(string); } } }; diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/BasicRecorder.java b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/BasicRecorder.java index fabddba4f..3c9652fc5 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/BasicRecorder.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/BasicRecorder.java @@ -241,12 +241,12 @@ private void hangingPlace(@NotNull HangingPlaceEvent event) { if (recData.getWhitelistMode()) { //white list --> blocks that are allowed to be broken if (recData.getWBBlocks().contains(usedMaterial) && mgm.getActivatePlayerRecorder()) { - recData.addEntity(event.getEntity(), mgPlayer, true); + recData.addEntity(event.getEntity(), mgPlayer, EntityData.ChangeType.CREATED); return; } //black list --> blocks that are not allowed to be broken } else if (!recData.getWBBlocks().contains(usedMaterial) && mgm.getActivatePlayerRecorder()) { - recData.addEntity(event.getEntity(), mgPlayer, true); + recData.addEntity(event.getEntity(), mgPlayer, EntityData.ChangeType.CREATED); return; } @@ -276,7 +276,7 @@ private void animalHurt(@NotNull EntityDamageByEntityEvent event) { if (mgPlayer != null) { if (mgPlayer.isInMinigame() && mgPlayer.getMinigame().getActivatePlayerRecorder()) { - mgPlayer.getMinigame().getRecorderData().addEntity(animal, mgPlayer, false); + mgPlayer.getMinigame().getRecorderData().addEntity(animal, mgPlayer, EntityData.ChangeType.REMOVED); } } } @@ -299,7 +299,7 @@ private void hangingBreak(@NotNull HangingBreakByEntityEvent event) { } if (mgPlayer != null) { if (mgPlayer.isInMinigame() && mgPlayer.getMinigame().getActivatePlayerRecorder()) { - mgPlayer.getMinigame().getRecorderData().addEntity(event.getEntity(), mgPlayer, false); + mgPlayer.getMinigame().getRecorderData().addEntity(event.getEntity(), mgPlayer, EntityData.ChangeType.REMOVED); } } } @@ -313,7 +313,7 @@ private void arrowShoot(@NotNull EntityShootBowEvent event) { MinigamePlayer mgPlayer = playerManager.getMinigamePlayer(player); if (mgPlayer.isInMinigame() && mgPlayer.getMinigame().getActivatePlayerRecorder()) { - mgPlayer.getMinigame().getRecorderData().addEntity(event.getProjectile(), mgPlayer, true); + mgPlayer.getMinigame().getRecorderData().addEntity(event.getProjectile(), mgPlayer, EntityData.ChangeType.CREATED); } } } @@ -327,7 +327,7 @@ private void throwEnderPearl(@NotNull ProjectileLaunchEvent event) { MinigamePlayer mgPlayer = playerManager.getMinigamePlayer(player); if (mgPlayer.isInMinigame() && mgPlayer.getMinigame().getActivatePlayerRecorder()) { - mgPlayer.getMinigame().getRecorderData().addEntity(event.getEntity(), mgPlayer, true); + mgPlayer.getMinigame().getRecorderData().addEntity(event.getEntity(), mgPlayer, EntityData.ChangeType.CREATED); } } } @@ -407,7 +407,7 @@ private void vehicleDestroy(@NotNull VehicleDestroyEvent event) { Minigame mg = mgPlayer.getMinigame(); if (mgPlayer.isInMinigame() && mg.getActivatePlayerRecorder()) { - mg.getRecorderData().addEntity(event.getVehicle(), mgPlayer, false); + mg.getRecorderData().addEntity(event.getVehicle(), mgPlayer, EntityData.ChangeType.REMOVED); } } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/EntityData.java b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/EntityData.java index 08602990d..f335a608c 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/EntityData.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/EntityData.java @@ -4,6 +4,7 @@ import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.entity.Entity; +import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; @@ -19,27 +20,30 @@ public class EntityData { private final @NotNull UUID uuid; //type of entity private final @NotNull EntityType entType; + // data (not including location) + private final @Nullable EntitySnapshot snapshot; //location the entity had when it was changed private final @NotNull Location entLocation; // the player who has changed the entity. If null, the entity doesn't get reset if the player left the minigame private final @Nullable MinigamePlayer player; // was this entity created and needs to removed or was it changed / killed? - private final boolean created; + private final @NotNull ChangeType changeType; /** * @param entity the entity to store data of * @param modifier the player who was the first one to change this entity, * might be null in case there was no player, or the minigame will be reset at the end, * regardless if players are joining / leaving it - * @param created if the entity was created and therefor has to be killed to reset the minigame + * @param changeType if the entity was created and therefor has to be killed to reset the minigame * or if it was changed / killed */ - public EntityData(@NotNull Entity entity, @Nullable MinigamePlayer modifier, boolean created) { + public EntityData(@NotNull Entity entity, @Nullable MinigamePlayer modifier, @NotNull ChangeType changeType) { this.uuid = entity.getUniqueId(); + this.snapshot = entity.createSnapshot(); this.entType = entity.getType(); - this.entLocation = entity.getLocation(); + this.entLocation = entity.getLocation().clone(); this.player = modifier; - this.created = created; + this.changeType = changeType; } /** @@ -60,8 +64,8 @@ public EntityData(@NotNull Entity entity, @Nullable MinigamePlayer modifier, boo return player; } - public boolean wasCreated() { - return created; + public @NotNull ChangeType getChangeType() { + return changeType; } /** @@ -71,10 +75,20 @@ public EntityType getEntityType() { return entType; } + public @Nullable EntitySnapshot getSnapshot() { + return snapshot; + } + /** * get the location the entity had when it was recorded */ public Location getEntityLocation() { return entLocation; } + + public enum ChangeType { + CREATED, + REMOVED, + CHANGED // todo record changed entities + } } diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RecorderData.java b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RecorderData.java index ed14a2f8b..53162b300 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RecorderData.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RecorderData.java @@ -14,6 +14,8 @@ import org.bukkit.block.Chest; import org.bukkit.block.DoubleChest; import org.bukkit.block.data.Hangable; +import org.bukkit.craftbukkit.entity.CraftEntity; +import org.bukkit.craftbukkit.entity.CraftEntitySnapshot; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Entity; import org.bukkit.event.Listener; @@ -204,17 +206,18 @@ public void addInventory(@NotNull MgBlockData bdata, @NotNull InventoryHolder ih } //add an entity to get reset - public void addEntity(@NotNull Entity ent, @Nullable MinigamePlayer player, boolean created) { + public void addEntity(@NotNull Entity ent, @Nullable MinigamePlayer player, @NotNull EntityData.ChangeType changeType) { EntityData oldData = entityData.get(ent.getUniqueId()); if (oldData != null) { - if (oldData.wasCreated() && !created) { + if (oldData.getChangeType() == EntityData.ChangeType.CREATED && + changeType == EntityData.ChangeType.REMOVED) { entityData.remove(ent.getUniqueId()); return; } } - entityData.put(ent.getUniqueId(), new EntityData(ent, player, created)); + entityData.put(ent.getUniqueId(), new EntityData(ent, player, changeType)); } public boolean hasBlock(@NotNull Block block) { @@ -311,17 +314,38 @@ public void restoreEntities(@Nullable MinigamePlayer player) { EntityData nextEntityData = it.next(); if (player == null || player.equals(nextEntityData.getModifier())) { - if (nextEntityData.wasCreated()) { - Entity ent = nextEntityData.getEntity(); - // Entity needs to be removed - if (ent != null && ent.isValid()) { - ent.remove(); + switch (nextEntityData.getChangeType()) { + case CREATED -> { + Entity entity = nextEntityData.getEntity(); + // Entity needs to be removed + if (entity != null && entity.isValid()) { + entity.remove(); + } + } + case REMOVED -> { + if (nextEntityData.getSnapshot() != null) { + nextEntityData.getSnapshot().createEntity(nextEntityData.getEntityLocation()); + } else { + Location location = nextEntityData.getEntityLocation(); + location.getWorld().spawnEntity(location, nextEntityData.getEntityType()); + } + } + case CHANGED -> { + final Entity entity = nextEntityData.getEntity(); + if (entity != null && entity.isValid() && entity.getType() == nextEntityData.getEntityType()) { + if (nextEntityData.getSnapshot() != null) { + ((CraftEntity) entity).getHandle().load(((CraftEntitySnapshot) nextEntityData.getSnapshot()).getData()); + entity.teleportAsync(nextEntityData.getEntityLocation()); + } + } else { + if (nextEntityData.getSnapshot() != null) { + nextEntityData.getSnapshot().createEntity(nextEntityData.getEntityLocation()); + } else { + Location location = nextEntityData.getEntityLocation(); + location.getWorld().spawnEntity(location, nextEntityData.getEntityType()); + } + } } - } else { - // Entity needs to be spawned - //todo restore metadata like armor - Location location = nextEntityData.getEntityLocation(); - location.getWorld().spawnEntity(location, nextEntityData.getEntityType()); } it.remove(); diff --git a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RegenRecorder.java b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RegenRecorder.java index 33478f487..f090a986c 100644 --- a/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RegenRecorder.java +++ b/Minigames/src/main/java/au/com/mineauz/minigames/recorder/RegenRecorder.java @@ -43,7 +43,7 @@ public RegenRecorder(@NotNull Minigame minigame) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) private void vehicleCreate(@NotNull VehicleCreateEvent event) { if (minigame.hasPlayers() && minigame.isInRegenArea(event.getVehicle().getLocation())) { - recorderData.addEntity(event.getVehicle(), null, true); + recorderData.addEntity(event.getVehicle(), null, EntityData.ChangeType.CREATED); } } @@ -52,7 +52,7 @@ private void vehicleCreate(@NotNull VehicleCreateEvent event) { private void vehicleDestroy(@NotNull VehicleDestroyEvent event) { if (event.getAttacker() == null) { if (minigame.hasPlayers() && minigame.isInRegenArea(event.getVehicle().getLocation())) { - recorderData.addEntity(event.getVehicle(), null, false); + recorderData.addEntity(event.getVehicle(), null, EntityData.ChangeType.REMOVED); } } } @@ -66,7 +66,7 @@ private void animalDeath(@NotNull EntityDamageByEntityEvent event) { if (minigame.isInRegenArea(entityLoc)) { if (animal.getHealth() <= event.getDamage()) { - recorderData.addEntity(event.getEntity(), null, false); + recorderData.addEntity(event.getEntity(), null, EntityData.ChangeType.REMOVED); } } } @@ -77,7 +77,7 @@ private void animalDeath(@NotNull EntityDamageByEntityEvent event) { @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) private void mobSpawnEvent(@NotNull CreatureSpawnEvent event) { if (minigame.hasPlayers() && minigame.isInRegenArea(event.getLocation())) { - recorderData.addEntity(event.getEntity(), null, true); + recorderData.addEntity(event.getEntity(), null, EntityData.ChangeType.CREATED); } } @@ -111,7 +111,7 @@ private void itemDrop(@NotNull ItemSpawnEvent event) { if (minigame.hasPlayers()) { Location ent = event.getLocation(); if (minigame.isInRegenArea(ent)) { - recorderData.addEntity(event.getEntity(), null, true); + recorderData.addEntity(event.getEntity(), null, EntityData.ChangeType.CREATED); } } } @@ -126,11 +126,11 @@ private void physicalBlock(@NotNull EntityChangeBlockEvent event) { } if (event.getTo().hasGravity()) { if (minigame.hasPlayers() || event.getEntity().hasMetadata("FellInMinigame")) { - recorderData.addEntity(event.getEntity(), null, true); + recorderData.addEntity(event.getEntity(), null, EntityData.ChangeType.CREATED); } } else if (event.getEntityType() == EntityType.FALLING_BLOCK && minigame.hasPlayers()) { event.getEntity().setMetadata("FellInMinigame", new FixedMetadataValue(Minigames.getPlugin(), true)); - recorderData.addEntity(event.getEntity(), null, true); + recorderData.addEntity(event.getEntity(), null, EntityData.ChangeType.CREATED); } } } @@ -141,7 +141,7 @@ private void cartHopperPickup(@NotNull InventoryPickupItemEvent event) { if (minigame.hasPlayers() && event.getInventory().getHolder() instanceof HopperMinecart) { Location loc = ((HopperMinecart) event.getInventory().getHolder()).getLocation(); if (minigame.isInRegenArea(loc)) { - recorderData.addEntity((HopperMinecart) event.getInventory().getHolder(), null, false); + recorderData.addEntity((HopperMinecart) event.getInventory().getHolder(), null, EntityData.ChangeType.REMOVED); } } } @@ -155,13 +155,13 @@ private void cartMoveItem(@NotNull InventoryMoveItemEvent event) { if (event.getInitiator().getHolder() instanceof HopperMinecart hopperMinecart) { loc = hopperMinecart.getLocation().clone(); if (minigame.isInRegenArea(loc)) - recorderData.addEntity((Entity) event.getInitiator().getHolder(), null, false); + recorderData.addEntity((Entity) event.getInitiator().getHolder(), null, EntityData.ChangeType.REMOVED); } if (event.getDestination().getHolder() instanceof HopperMinecart hopperMinecart) { loc = hopperMinecart.getLocation().clone(); if (minigame.isInRegenArea(loc)) - recorderData.addEntity((Entity) event.getInitiator().getHolder(), null, false); + recorderData.addEntity((Entity) event.getInitiator().getHolder(), null, EntityData.ChangeType.REMOVED); } } diff --git a/Regions/src/main/java/au/com/mineauz/minigamesregions/actions/SpawnEntityAction.java b/Regions/src/main/java/au/com/mineauz/minigamesregions/actions/SpawnEntityAction.java index 4209a3bfa..a29d5dce6 100644 --- a/Regions/src/main/java/au/com/mineauz/minigamesregions/actions/SpawnEntityAction.java +++ b/Regions/src/main/java/au/com/mineauz/minigamesregions/actions/SpawnEntityAction.java @@ -1,63 +1,46 @@ package au.com.mineauz.minigamesregions.actions; -import au.com.mineauz.minigames.Minigames; -import au.com.mineauz.minigames.config.EnumFlag; import au.com.mineauz.minigames.menu.*; import au.com.mineauz.minigames.objects.MinigamePlayer; +import au.com.mineauz.minigames.recorder.EntityData; +import au.com.mineauz.minigamesregions.Main; import au.com.mineauz.minigamesregions.Node; import au.com.mineauz.minigamesregions.Region; +import au.com.mineauz.minigamesregions.config.EntitySnapshotFlag; import au.com.mineauz.minigamesregions.language.RegionLangKey; import au.com.mineauz.minigamesregions.language.RegionMessageManager; +import io.papermc.paper.adventure.PaperAdventure; import net.kyori.adventure.text.Component; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import org.bukkit.Bukkit; +import org.bukkit.Location; import org.bukkit.Material; +import org.bukkit.NamespacedKey; import org.bukkit.configuration.file.FileConfiguration; +import org.bukkit.craftbukkit.entity.CraftEntitySnapshot; +import org.bukkit.craftbukkit.entity.CraftEntityType; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; -import org.bukkit.event.entity.CreatureSpawnEvent; -import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.entity.Zombie; +import org.bukkit.persistence.PersistentDataType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.*; - -/* - * todo - * Entity settings: - * rotation - * - * Living Entity Settings: - * Potion effect - * EntityEquipment - * Ageable: - * setAge - * --> Breeadble - * setAgeLock - */ +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class SpawnEntityAction extends AAction { - /** - * Contains all entities that are problematic to spawn as is. - * Some problems may get resolved, if their (default)settings get added in the future; - * others probably stay problematic and shouldn't be spawn able like players - */ - private final Set NOT_SPAWNABLE = Set.of( //todo enabled feature by world - EntityType.AREA_EFFECT_CLOUD, // todo needs effect - EntityType.BLOCK_DISPLAY, // todo needs block state/data and display settings - EntityType.ITEM, // todo needs ItemMeta - EntityType.FALLING_BLOCK, // todo needs block state/data - EntityType.FISHING_BOBBER, // needs a fishing rod; we can't guarantee this - EntityType.GLOW_ITEM_FRAME, // hanging items need support and direction; we can't guarantee this - EntityType.ITEM_DISPLAY, // todo needs ItemMeta and display settings - EntityType.ITEM_FRAME, // hanging items need support and direction; we can't guarantee this - EntityType.LEASH_KNOT, // hanging items need support also does not easy leash an entity; we can't guarantee this - EntityType.LIGHTNING_BOLT, // todo needs lightning settings - EntityType.PAINTING, // hanging items need support and direction; we can't guarantee this - EntityType.PLAYER, // we don't support npcs; todo maybe in the future integrate citizens support? - EntityType.TEXT_DISPLAY, // todo needs text and display settings - EntityType.UNKNOWN // not a spawn able entity type - ); + private static final @NotNull NamespacedKey MINIGAME_ENTITY_KEY = new NamespacedKey(Main.getPlugin(), "minigame"); + private final @NotNull EntitySnapshotFlag entitySnapshotFlag = new EntitySnapshotFlag(getDefaultSnapshot(), "entity"); - private final EnumFlag type = new EnumFlag<>(EntityType.ZOMBIE, "type"); - //private final Map> settings = new HashMap<>(); // todo once Paper stops relocation use ((CraftEntity)entity).getHandle().saveWithoutId(nbt); instead of an own bad implementation + private static @NotNull EntitySnapshot getDefaultSnapshot() { + return Bukkit.getWorlds().getFirst().createEntity(new Location(Bukkit.getWorlds().getFirst(), 0, 0, 0), Zombie.class).createSnapshot(); + } protected SpawnEntityAction(@NotNull String name) { super(name); @@ -79,16 +62,18 @@ protected SpawnEntityAction(@NotNull String name) { } @Override - public @NotNull Map<@NotNull Component, @Nullable Component> describe() { //todo - Map out = new HashMap<>(2); + public @NotNull Map<@NotNull Component, @Nullable Component> describe() { + Map out = new LinkedHashMap<>(2); + out.put(RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_TYPE_NAME), Component.translatable(entitySnapshotFlag.getFlagOrDefault().getEntityType().translationKey())); - out.put(RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_TYPE_NAME), Component.text(type.getFlag().translationKey())); + if (entitySnapshotFlag.getFlagOrDefault().getEntityType().isAlive()) { + String customName = ((CraftEntitySnapshot) entitySnapshotFlag.getFlagOrDefault()).getData().getString("CustomName"); - /* - if (type.getFlag().isAlive() && settings.containsKey("customName")) { - out.put(RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_NAME_NAME), - MiniMessage.miniMessage().deserialize((String) settings.get("customName").getObject())); - }*/ + if (!customName.isBlank()) { + out.put(RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_CUSTOMNAME_NAME), + PaperAdventure.asAdventure(net.minecraft.network.chat.Component.Serializer.fromJson(customName, MinecraftServer.getServer().registryAccess()))); + } + } return out; } @@ -115,451 +100,68 @@ public void executeNodeAction(@NotNull MinigamePlayer mgPlayer, @NotNull Node no return; } debug(mgPlayer, node); - node.getLocation().getWorld().spawnEntity(node.getLocation(), type.getFlag(), CreatureSpawnEvent.SpawnReason.CUSTOM, entity -> { - /* - if (settings.containsKey("velocity")) { - final Vector velocity = (Vector) settings.get("velocity").getObject(); - Bukkit.getScheduler().scheduleSyncDelayedTask(Main.getPlugin(), () -> entity.setVelocity(velocity)); - } - - if (settings.containsKey("customName")) { - entity.customName(MiniMessage.miniMessage().deserialize((String) settings.get("customName").getObject())); - } - - if (settings.containsKey("customNameVisible")) { - entity.setCustomNameVisible((Boolean) settings.get("customNameVisible").getObject()); - } - - if (settings.containsKey("visualFire")) { - entity.setVisualFire((Boolean) settings.get("visualFire").getObject()); - } - - if (settings.containsKey("persistent")) { - entity.setPersistent((Boolean) settings.get("persistent").getObject()); - } - - if (settings.containsKey("glowing")) { - entity.setGlowing((Boolean) settings.get("glowing").getObject()); - } - if (settings.containsKey("invulnerable")) { - entity.setInvulnerable((Boolean) settings.get("invulnerable").getObject()); - } - - if (settings.containsKey("silent")) { - entity.setSilent((Boolean) settings.get("silent").getObject()); - } - - if (settings.containsKey("hasGravity")) { - entity.setGravity((Boolean) settings.get("hasGravity").getObject()); - } + Entity entity = entitySnapshotFlag.getFlagOrDefault().createEntity(node.getLocation()); + entity.getPersistentDataContainer().set(MINIGAME_ENTITY_KEY, PersistentDataType.STRING, node.getMinigame().getName()); //todo use in recorder to despawn + add parameter for specific Minigame - if (entity instanceof LivingEntity livingEntity) { - if (settings.containsKey("canPickupItems")) { - livingEntity.setCanPickupItems((Boolean) settings.get("canPickupItems").getObject()); - } - - if (settings.containsKey("hasAI")) { - livingEntity.setAI((Boolean) settings.get("hasAI").getObject()); - } - - if (settings.containsKey("isCollidable")) { - livingEntity.setCollidable((Boolean) settings.get("isCollidable").getObject()); - } - }*/ - - entity.setMetadata("MinigameEntity", new FixedMetadataValue(Minigames.getPlugin(), true)); //todo use in recorder to despawn + add parameter for specific Minigame - mgPlayer.getMinigame().getRecorderData().addEntity(entity, mgPlayer, true); - }); + mgPlayer.getMinigame().getRecorderData().addEntity(entity, mgPlayer, EntityData.ChangeType.CREATED); } @Override public void saveArguments(@NotNull FileConfiguration config, @NotNull String path) { - type.saveValue(config, path); - - /* // temp - char configSeparator = config.options().pathSeparator(); - for (Map.Entry> entry : settings.entrySet()) { - config.set(path + configSeparator + "settings" + configSeparator + entry.getKey(), entry.getValue().serialize()); - }*/ + entitySnapshotFlag.saveValue(config, path); } @Override public void loadArguments(@NotNull FileConfiguration config, @NotNull String path) { - type.loadValue(config, path); - /* - settings.clear(); - char configSeparator = config.options().pathSeparator(); - ConfigurationSection section = config.getConfigurationSection(path + configSeparator + "settings"); - if (section != null) { // may was empty - Set keys = section.getKeys(false); - - for (String key : keys) { - ConfigSerializableBridge serializableBridge = ConfigSerializableBridge.deserialize(config.get(path + configSeparator + "settings" + configSeparator + key)); - - if (serializableBridge != null) { - settings.put(key, serializableBridge); - } else { - Minigames.getCmpnntLogger().warn("Key \"" + key + "\" of ConfigSerializableBridge in SpawnEntityAction of path \"" + path + configSeparator + "settings" + configSeparator + key + "\" failed to load!"); - } - } - }*/ + entitySnapshotFlag.loadValue(config, path); } @Override public boolean displayMenu(@NotNull MinigamePlayer mgPlayer, @NotNull Menu previous) { Menu menu = new Menu(3, getDisplayname(), mgPlayer); menu.addItem(new MenuItemBack(previous), menu.getSize() - 9); - List options = new ArrayList<>(); - for (EntityType type : EntityType.values()) { - if (!NOT_SPAWNABLE.contains(type)) { + + final MenuItem entitySelector = entitySnapshotFlag.getMenuItem(Material.SPAWNER, RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_SELECT_NAME)); + entitySelector.update(); + + final EntityType[] entityTypes = EntityType.values(); + List options = new ArrayList<>(entityTypes.length); + for (EntityType type : entityTypes) { + if (type.isSpawnable()) { options.add(type); } } - menu.addItem(new MenuItemList<>(Material.SKELETON_SKULL, RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_TYPE_NAME), new Callback<>() { //todo spawn egg? - + menu.addItem(new MenuItemList<>(Material.SKELETON_SKULL, RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_TYPE_NAME), new Callback<>() { @Override public EntityType getValue() { - return type.getFlag(); + return entitySnapshotFlag.getFlagOrDefault().getEntityType(); } @Override public void setValue(EntityType value) { - type.setFlag(value); - } - }, options)); + final @NotNull CompoundTag nbt = ((CraftEntitySnapshot) entitySnapshotFlag.getFlagOrDefault()).getData(); - final MenuItemCustom customMenuItem = new MenuItemCustom(Material.CHEST, RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_SETTINGS_NAME)); - final Menu entitySettingsMenu = new Menu(6, RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_SETTINGS_NAME), mgPlayer); - final MinigamePlayer fply = mgPlayer; - customMenuItem.setClick(() -> { - if (type.getFlag().isAlive()) { - entitySettingsMenu.clearMenu(); + net.minecraft.world.entity.EntityType entitytypes = CraftEntityType.bukkitToMinecraft(value); + ResourceLocation minecraftkey = net.minecraft.world.entity.EntityType.getKey(entitytypes); + String StringID = entitytypes.canSerialize() && minecraftkey != null ? minecraftkey.toString() : null; - final MenuItemBack backButton = new MenuItemBack(menu); - entitySettingsMenu.addItem(backButton, entitySettingsMenu.getSize() - 1); - populateEntitySettings(entitySettingsMenu, mgPlayer); + if (StringID != null) { + nbt.putString("id", StringID); - entitySettingsMenu.displayMenu(fply); - return null; + entitySnapshotFlag.setFlag(CraftEntitySnapshot.create(nbt)); + entitySelector.update(); + } } - return customMenuItem.getDisplayItem(); - }); - menu.addItem(customMenuItem); + }, options)); menu.displayMenu(mgPlayer); return true; } - private void populateEntitySettings(@NotNull Menu entitySettingsMenu, @NotNull MinigamePlayer mgPlayer) { - /* - entitySettingsMenu.addItem(new MenuItemComponent(Material.NAME_TAG, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_NAME_NAME), new Callback<>() { - @Override - public Component getValue() { - ConfigSerializableBridge value = settings.get("customName"); - if (value == null) { - return Component.empty(); - } else { - return MiniMessage.miniMessage().deserialize((String) value.getObject()); - } - } - - @Override - public void setValue(Component value) { - settings.put("customName", new ConfigSerializableBridge<>(MiniMessage.miniMessage().serialize(value))); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.SPYGLASS, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_NAMEVISIBLE_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("customNameVisible"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("customNameVisible", new ConfigSerializableBridge<>(value)); - } - })); - - Menu velocityMenu = new Menu(3, RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VELOCITY_NAME), mgPlayer); - final MenuItemBack backButton = new MenuItemBack(entitySettingsMenu); - velocityMenu.addItem(backButton, velocityMenu.getSize() - 1); - - velocityMenu.addItem(new MenuItemDecimal(Material.ARROW, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VELOCITY_X_NAME), new Callback<>() { - @Override - public Double getValue() { - ConfigSerializableBridge value = settings.get("velocity"); - - if (value == null) { - return 0D; - } else { - return ((Vector) value.getObject()).getX(); - } - } - - @Override - public void setValue(Double value) { - Vector vector; - - ConfigSerializableBridge savedVelocity = settings.get("velocity"); - if (savedVelocity == null) { - vector = new Vector(value, 0, 0); - } else { - vector = (Vector) savedVelocity.getObject(); - vector.setX(value); - } - - settings.put("velocity", new ConfigSerializableBridge<>(vector)); - } - - - }, 0.5, 1, null, null)); - velocityMenu.addItem(new MenuItemDecimal(Material.ARROW, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VELOCITY_Y_NAME), new Callback<>() { - @Override - public Double getValue() { - ConfigSerializableBridge value = settings.get("velocity"); - - if (value == null) { - return 0D; - } else { - return ((Vector) value.getObject()).getY(); - } - } - - @Override - public void setValue(Double value) { - Vector vector; - - ConfigSerializableBridge savedVelocity = settings.get("velocity"); - if (savedVelocity == null) { - vector = new Vector(0, value, 0); - } else { - vector = (Vector) savedVelocity.getObject(); - vector.setY(value); - } - - settings.put("velocity", new ConfigSerializableBridge<>(vector)); - } - - - }, 0.5, 1, null, null)); - velocityMenu.addItem(new MenuItemDecimal(Material.ARROW, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VELOCITY_Z_NAME), new Callback<>() { - - @Override - public Double getValue() { - ConfigSerializableBridge value = settings.get("velocity"); - - if (value == null) { - return 0D; - } else { - return ((Vector) value.getObject()).getZ(); - } - } - - @Override - public void setValue(Double value) { - Vector vector; - - ConfigSerializableBridge savedVelocity = settings.get("velocity"); - if (savedVelocity == null) { - vector = new Vector(0, 0, value); - } else { - vector = (Vector) savedVelocity.getObject(); - vector.setZ(value); - } - - settings.put("velocity", new ConfigSerializableBridge<>(vector)); - } - }, 0.5, 1, null, null)); - entitySettingsMenu.addItem(new MenuItemPage(Material.FIREWORK_ROCKET, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VELOCITY_NAME), velocityMenu)); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.CAMPFIRE, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_VISUALFIRE_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("visualFire"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("visualFire", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.SLIME_BALL, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_PERSISTENT_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("persistent"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("persistent", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.GLOWSTONE_DUST, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_GLOWING_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("glowing"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("glowing", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.SHIELD, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_INVULNERABLE_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("invulnerable"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("invulnerable", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.SCULK_SENSOR, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_SILENT_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("silent"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("silent", new ConfigSerializableBridge<>(value)); - } - })); - - // don't overflow to next page - entitySettingsMenu.addItem(new MenuItemNewLine()); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.ELYTRA, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_GRAVITY_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("hasGravity"); - if (value == null) { - return true; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("hasGravity", new ConfigSerializableBridge<>(value)); - } - })); - - if (type.getFlag().isAlive()) { - entitySettingsMenu.addItem(new MenuItemNewLine()); - populateLivingEntitySettings(entitySettingsMenu, mgPlayer); - }*/ - } - - private void populateLivingEntitySettings(@NotNull Menu entitySettingsMenu, @NotNull MinigamePlayer mgPlayer) { - /* - entitySettingsMenu.addItem(new MenuItemNewLine()); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.HOPPER, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_PICKUPITEMS_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("canPickupItems"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("canPickupItems", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.LIGHT, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_AI_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("hasAI"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("hasAI", new ConfigSerializableBridge<>(value)); - } - })); - - entitySettingsMenu.addItem(new MenuItemBoolean(Material.GLASS, - RegionMessageManager.getMessage(RegionLangKey.MENU_ACTION_SPAWNENTITY_COLLIDABLE_NAME), new Callback<>() { - @Override - public Boolean getValue() { - ConfigSerializableBridge value = settings.get("isCollidable"); - if (value == null) { - return false; - } else { - return (Boolean) value.getObject(); - } - } - - @Override - public void setValue(Boolean value) { - settings.put("isCollidable", new ConfigSerializableBridge<>(value)); - } - }));*/ + public static @NotNull NamespacedKey getMINIGAME_ENTITY_KEY() { + return MINIGAME_ENTITY_KEY; } } diff --git a/Regions/src/main/java/au/com/mineauz/minigamesregions/config/EntitySnapshotFlag.java b/Regions/src/main/java/au/com/mineauz/minigamesregions/config/EntitySnapshotFlag.java new file mode 100644 index 000000000..e09067d37 --- /dev/null +++ b/Regions/src/main/java/au/com/mineauz/minigamesregions/config/EntitySnapshotFlag.java @@ -0,0 +1,61 @@ +package au.com.mineauz.minigamesregions.config; + +import au.com.mineauz.minigames.config.AFlag; +import au.com.mineauz.minigames.menu.Callback; +import au.com.mineauz.minigamesregions.menu.MenuItemSelectEntity; +import net.kyori.adventure.text.Component; +import net.minecraft.nbt.CompoundTag; +import org.bukkit.Material; +import org.bukkit.configuration.Configuration; +import org.bukkit.craftbukkit.entity.CraftEntitySnapshot; +import org.bukkit.craftbukkit.util.CraftNBTTagConfigSerializer; +import org.bukkit.entity.EntitySnapshot; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.List; + +public class EntitySnapshotFlag extends AFlag { + public EntitySnapshotFlag(@Nullable EntitySnapshot value, @NotNull String name) { + super(name, value, value); + } + + @Override + public void saveValue(@NotNull Configuration config, @NotNull String path) { + if (getFlag() != null && !getFlag().equals(getDefaultFlag())) { + config.set(path + config.options().pathSeparator() + getName(), CraftNBTTagConfigSerializer.serialize(((CraftEntitySnapshot) getFlag()).getData())); + } else { + config.set(path + config.options().pathSeparator() + getName(), null); + } + } + + @Override + public void loadValue(@NotNull Configuration config, @NotNull String path) { + final @Nullable String string = config.getString(path + config.options().pathSeparator() + getName()); + + if (string != null) { + if (CraftNBTTagConfigSerializer.deserialize(string) instanceof CompoundTag tag) { + setFlag(CraftEntitySnapshot.create(tag)); + return; + } + } + + setFlag(getDefaultFlag()); + } + + @Override + public @NotNull MenuItemSelectEntity getMenuItem(@Nullable Material displayMat, @Nullable Component name, + @Nullable List<@NotNull Component> description) { + return new MenuItemSelectEntity(displayMat, name, description, new Callback<>() { + @Override + public EntitySnapshot getValue() { + return getFlag(); + } + + @Override + public void setValue(EntitySnapshot value) { + setFlag(value); + } + }); + } +} diff --git a/Regions/src/main/java/au/com/mineauz/minigamesregions/language/RegionLangKey.java b/Regions/src/main/java/au/com/mineauz/minigamesregions/language/RegionLangKey.java index 8e9ae846b..5c7a14da0 100644 --- a/Regions/src/main/java/au/com/mineauz/minigamesregions/language/RegionLangKey.java +++ b/Regions/src/main/java/au/com/mineauz/minigamesregions/language/RegionLangKey.java @@ -186,6 +186,7 @@ public enum RegionLangKey implements LangKey { MENU_CONDITION_TEAMSCORERANGE_NAME("menu.condition.teamScoreRange.name"), MENU_ENTITY_CUSTOMNAME_NAME("menu.entity.customName.name"), MENU_ENTITY_TYPE_NAME("menu.entity.type.name"), + MENU_ENTITY_SELECT_NAME("menu.entity.select.name"), MENU_EXECUTOR_ACTION("menu.executor.action"), MENU_EXECUTOR_ADD_NAME("menu.executor.add.name"), MENU_EXECUTOR_EDIT("menu.executor.edit"), @@ -210,6 +211,7 @@ public enum RegionLangKey implements LangKey { MENU_REGIONSNODES_NAME("menu.regionsNodes.name"), MENU_REGION_NAME("menu.region.name"), MENU_RNDCHANCE_SETPERCENT_NAME("menu.condition.randomChance.percentage"), + MENU_SELECT_ENTITY_CLICK_ENTITY("menu.select_entity.click_entity"), MENU_TEAM_DESCRIPTION("menu.actions.team.description"), MENU_TEAM_NAME("menu.team.name"), MENU_TOOL_NODE_DESCRIPTION("menu.tool.node.description"), diff --git a/Regions/src/main/java/au/com/mineauz/minigamesregions/menu/MenuItemSelectEntity.java b/Regions/src/main/java/au/com/mineauz/minigamesregions/menu/MenuItemSelectEntity.java new file mode 100644 index 000000000..5a94e0a51 --- /dev/null +++ b/Regions/src/main/java/au/com/mineauz/minigamesregions/menu/MenuItemSelectEntity.java @@ -0,0 +1,127 @@ +package au.com.mineauz.minigamesregions.menu; + +import au.com.mineauz.minigames.MinigameUtils; +import au.com.mineauz.minigames.managers.language.MinigameMessageManager; +import au.com.mineauz.minigames.managers.language.MinigameMessageType; +import au.com.mineauz.minigames.managers.language.MinigamePlaceHolderKey; +import au.com.mineauz.minigames.menu.Callback; +import au.com.mineauz.minigames.menu.MenuItem; +import au.com.mineauz.minigames.menu.consumer.EntityConsumer; +import au.com.mineauz.minigames.objects.MinigamePlayer; +import au.com.mineauz.minigamesregions.Main; +import au.com.mineauz.minigamesregions.language.RegionLangKey; +import au.com.mineauz.minigamesregions.language.RegionMessageManager; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import org.bukkit.*; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntitySnapshot; +import org.bukkit.entity.EntityType; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.SpawnEggMeta; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.time.Duration; +import java.util.List; + +public class MenuItemSelectEntity extends MenuItem implements EntityConsumer { + private final static String DESCRIPTION_TOKEN = "Entity_description"; + private final @NotNull Callback entitySnapshotCallback; + + public MenuItemSelectEntity(@Nullable Material displayMat, @Nullable Component name, @NotNull Callback c) { + super(displayMat, name); + entitySnapshotCallback = c; + } + + public MenuItemSelectEntity(@Nullable Material displayMat, @Nullable Component name, + @Nullable List<@NotNull Component> description, @NotNull Callback c) { + super(displayMat, name, description); + entitySnapshotCallback = c; + } + + @Override + public ItemStack onClickWithItem(@NotNull ItemStack item) { + if (item.getItemMeta() instanceof SpawnEggMeta spawnEggMeta) { + final @Nullable EntitySnapshot snapshot = spawnEggMeta.getSpawnedEntity(); + + if (snapshot != null) { + if (snapshot.getEntityType().isSpawnable()) { + entitySnapshotCallback.setValue(snapshot); + update(); + } else { + Main.getPlugin().getComponentLogger().warn("MenuItemSelectEntity was clicked with an spawnegg containing a non-spawnable entity: {}", snapshot.getEntityType().getKey()); + } + } else { + final @Nullable EntityType entityType = Registry.ENTITY_TYPE.get(item.getType().getKey()); + + if (entityType != null && entityType.isSpawnable()) { + entitySnapshotCallback.setValue(Bukkit.getWorlds().getFirst().createEntity(new Location(Bukkit.getWorlds().getFirst(), 0, 0, 0), entityType.getEntityClass()).createSnapshot()); + update(); + } else { + Main.getPlugin().getComponentLogger().warn("MenuItemSelectEntity was clicked with an spawnegg, but I couldn't find any spawnable entity: {}, coming from {}", entityType == null ? null : entityType.getKey().asString(), item.getType().getKey().asString()); + } + } + } + + return super.onClickWithItem(item); + } + + @Override + public @Nullable ItemStack onDoubleClick() { + MinigamePlayer mgPlayer = getContainer().getViewer(); + mgPlayer.setNoClose(true); + mgPlayer.getPlayer().closeInventory(); + final int reopenSeconds = 10; + + MinigameMessageManager.sendMessage(mgPlayer, MinigameMessageType.INFO, + RegionMessageManager.getMessage(RegionLangKey.MENU_SELECT_ENTITY_CLICK_ENTITY, + Placeholder.component(MinigamePlaceHolderKey.TYPE.getKey(), getName()), + Placeholder.component(MinigamePlaceHolderKey.TIME.getKey(), MinigameUtils.convertTime(Duration.ofSeconds(reopenSeconds))))); + mgPlayer.setManualEntry(this); + getContainer().startReopenTimer(reopenSeconds); + + + return super.onDoubleClick(); + } + + @Override + public void acceptEntity(@NotNull Entity entity) { + entitySnapshotCallback.setValue(entity.createSnapshot()); + update(); + + getContainer().cancelReopenTimer(); + getContainer().displayMenu(getContainer().getViewer()); + } + + public void update() { + Material displayType; + + // fist try spawn egg + displayType = Registry.MATERIAL.get(NamespacedKey.minecraft(entitySnapshotCallback.getValue().getEntityType().getKey().getKey() + "_spawn_egg")); + + if (displayType == null) { + // did not work. Maybe there is an item with the same key, like in case of boats or arrows? + displayType = Registry.MATERIAL.get(entitySnapshotCallback.getValue().getEntityType().getKey()); + + if (displayType == null) { + displayType = Material.SPAWNER; + } + } + + ItemStack newDisplayItem = getDisplayItem().withType(displayType); + + if (newDisplayItem instanceof SpawnEggMeta spawnEggMeta) { + spawnEggMeta.setSpawnedEntity(entitySnapshotCallback.getValue()); + + newDisplayItem.setItemMeta(spawnEggMeta); + } + + setDisplayItem(newDisplayItem); + + setDescriptionPart(DESCRIPTION_TOKEN, List.of( + RegionMessageManager.getMessage(RegionLangKey.MENU_ENTITY_TYPE_NAME, + Placeholder.component(MinigamePlaceHolderKey.ENTITY.getKey(), + Component.translatable(entitySnapshotCallback.getValue().getEntityType().translationKey()))))); + } +} diff --git a/Regions/src/main/resources/minigames-regions.properties b/Regions/src/main/resources/minigames-regions.properties index 03e3d3c51..26f028e20 100644 --- a/Regions/src/main/resources/minigames-regions.properties +++ b/Regions/src/main/resources/minigames-regions.properties @@ -171,6 +171,7 @@ menu.condition.playerScoreRange.name=Player score range menu.condition.playerXPRange.name=Player XP range menu.condition.randomChance.name=Random chance menu.condition.randomChance.percentage=Percentage chance +menu.select_entity.click_entity=Click an entity to set Data for , the menu will automatically reopen in