wip: added persistent data tags on items
This commit is contained in:
		| @@ -11,30 +11,52 @@ import org.bukkit.inventory.ItemStack; | |||||||
| import org.bukkit.inventory.Recipe; | import org.bukkit.inventory.Recipe; | ||||||
| import org.bukkit.inventory.ShapedRecipe; | import org.bukkit.inventory.ShapedRecipe; | ||||||
| import org.bukkit.inventory.meta.ItemMeta; | import org.bukkit.inventory.meta.ItemMeta; | ||||||
|  | import org.bukkit.persistence.PersistentDataContainer; | ||||||
|  | import org.bukkit.persistence.PersistentDataType; | ||||||
| import org.jetbrains.annotations.NotNull; | import org.jetbrains.annotations.NotNull; | ||||||
|  | import org.jetbrains.annotations.Nullable; | ||||||
|  |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  | import java.util.Objects; | ||||||
| import java.util.Optional; | import java.util.Optional; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  |  | ||||||
| public class PixelBlockItem { | public class PixelBlockItem { | ||||||
|     public static UUID unusedBlockID = UUID.fromString("98fdf0ae-c3ab-4ef7-ae25-efd518d600de"); |  | ||||||
|     public static final String itemTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzE5NGU5ZTc3NTdkMDZkNmY1ZTViZTg0NTQ4YTdjYjUyMTczZDY4Y2NmODAyZDIxMTI3NWQzMWNkYmEwYTA2ZSJ9fX0="; |  | ||||||
|     public static final NamespacedKey recipeKey = new NamespacedKey(PixelBlocksPlugin.plugin, "pixelblock"); |     public static final NamespacedKey recipeKey = new NamespacedKey(PixelBlocksPlugin.plugin, "pixelblock"); | ||||||
|  |     public static NamespacedKey idProperty = new NamespacedKey(PixelBlocksPlugin.plugin, "id"); | ||||||
|  |     public static NamespacedKey ownerProperty = new NamespacedKey(PixelBlocksPlugin.plugin, "owner"); | ||||||
|  |  | ||||||
|  |     public static final String itemTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYzE5NGU5ZTc3NTdkMDZkNmY1ZTViZTg0NTQ4YTdjYjUyMTczZDY4Y2NmODAyZDIxMTI3NWQzMWNkYmEwYTA2ZSJ9fX0="; | ||||||
|  |  | ||||||
|  |     public record BlockInfo(UUID id, @Nullable UUID owner) { | ||||||
|  |         public boolean hasOwner() { | ||||||
|  |             return owner != null; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     public static @Nullable BlockInfo getBlockInfo(ItemStack item) { | ||||||
|  |         PersistentDataContainer container = item.getItemMeta().getPersistentDataContainer(); | ||||||
|  |         if(!container.has(idProperty)) return null; | ||||||
|  |         UUID blockId = UUID.fromString(Objects.requireNonNull(container.get(idProperty, PersistentDataType.STRING))); | ||||||
|  |         UUID ownerId = container.has(ownerProperty) | ||||||
|  |             ? UUID.fromString(Objects.requireNonNull(container.get(ownerProperty, PersistentDataType.STRING))) | ||||||
|  |             : null; | ||||||
|  |         return new BlockInfo(blockId, ownerId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) { |     public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) { | ||||||
|         String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString()); |         String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString()); | ||||||
|  |  | ||||||
|         ItemStack itemStack = HeadUtil.getCustomTextureHead(itemTexture); |         ItemStack itemStack = HeadUtil.getCustomTextureHead(itemTexture); | ||||||
|         ItemMeta meta = itemStack.getItemMeta(); |         ItemMeta meta = itemStack.getItemMeta(); | ||||||
|         meta.itemName(Component.text(block.blockUUID.toString())); |         meta.setMaxStackSize(1); | ||||||
|  |         meta.getPersistentDataContainer().set(idProperty, PersistentDataType.STRING, block.blockUUID.toString()); | ||||||
|  |         meta.getPersistentDataContainer().set(ownerProperty, PersistentDataType.STRING, block.ownerUUID.toString()); | ||||||
|         meta.displayName(Component.text("Pixelblock von " + ownerName)); |         meta.displayName(Component.text("Pixelblock von " + ownerName)); | ||||||
|         meta.lore(List.of( |         meta.lore(List.of( | ||||||
|             Component.text(ownerName + " ist der Besitzer dieses Blocks."), |             Component.text(ownerName + " ist der Besitzer dieses Blocks."), | ||||||
|             Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!"), |             Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!"), | ||||||
|             Component.text(block.blockUUID.toString()).color(NamedTextColor.DARK_GRAY) |             Component.text(block.blockUUID.toString()).color(NamedTextColor.DARK_GRAY) | ||||||
|         )); |         )); | ||||||
|         meta.setEnchantmentGlintOverride(true); |  | ||||||
|         itemStack.setItemMeta(meta); |         itemStack.setItemMeta(meta); | ||||||
|  |  | ||||||
|         return itemStack; |         return itemStack; | ||||||
| @@ -43,13 +65,13 @@ public class PixelBlockItem { | |||||||
|     public static @NotNull ItemStack getEmptyPixelBlock() { |     public static @NotNull ItemStack getEmptyPixelBlock() { | ||||||
|         ItemStack item = HeadUtil.getCustomTextureHead(itemTexture); |         ItemStack item = HeadUtil.getCustomTextureHead(itemTexture); | ||||||
|         ItemMeta meta = item.getItemMeta(); |         ItemMeta meta = item.getItemMeta(); | ||||||
|  |         meta.setMaxStackSize(1); | ||||||
|         meta.displayName(Component.text("Leerer Pixelblock")); |         meta.displayName(Component.text("Leerer Pixelblock")); | ||||||
|         meta.lore(List.of( |         meta.lore(List.of( | ||||||
|             Component.text("Der erste Spieler, der den Block platziert wird zum Besitzer des Blocks."), |             Component.text("Der erste Spieler, der den Block platziert wird zum Besitzer des Blocks."), | ||||||
|             Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!") |             Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!") | ||||||
|         )); |         )); | ||||||
|         meta.setEnchantmentGlintOverride(true); |         meta.getPersistentDataContainer().set(idProperty, PersistentDataType.STRING, UUID.randomUUID().toString()); | ||||||
|         meta.itemName(Component.text(unusedBlockID.toString())); |  | ||||||
|         item.setItemMeta(meta); |         item.setItemMeta(meta); | ||||||
|         return item; |         return item; | ||||||
|     } |     } | ||||||
| @@ -61,7 +83,7 @@ public class PixelBlockItem { | |||||||
|         recipe.setIngredient('B', Material.DIAMOND_BLOCK); |         recipe.setIngredient('B', Material.DIAMOND_BLOCK); | ||||||
|         recipe.setIngredient('C', Material.HEART_OF_THE_SEA); |         recipe.setIngredient('C', Material.HEART_OF_THE_SEA); | ||||||
|         recipe.setIngredient('D', Material.GRASS_BLOCK); |         recipe.setIngredient('D', Material.GRASS_BLOCK); | ||||||
|         recipe.setIngredient('E', Material.GLOW_BERRIES); |         recipe.setIngredient('E', Material.END_CRYSTAL); | ||||||
|         return recipe; |         return recipe; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -52,7 +52,6 @@ public final class PixelBlocksPlugin extends JavaPlugin { | |||||||
|             new PlacePixelBlockListener(), |             new PlacePixelBlockListener(), | ||||||
|             new PreventInventorysListener(), |             new PreventInventorysListener(), | ||||||
|             new ExitPixelWorldListener(), |             new ExitPixelWorldListener(), | ||||||
|             new CraftPixelBlockListener(), |  | ||||||
|             new PreventIllegalBlocksListener(), |             new PreventIllegalBlocksListener(), | ||||||
|             new BreakPixelBlockListener(), |             new BreakPixelBlockListener(), | ||||||
|             new PlacePixelListener(), |             new PlacePixelListener(), | ||||||
|   | |||||||
| @@ -1,25 +0,0 @@ | |||||||
| package eu.mhsl.minecraft.pixelblocks.listeners; |  | ||||||
|  |  | ||||||
| import eu.mhsl.minecraft.pixelblocks.PixelBlockItem; |  | ||||||
| import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; |  | ||||||
| import org.bukkit.event.EventHandler; |  | ||||||
| import org.bukkit.event.Listener; |  | ||||||
| import org.bukkit.event.inventory.CraftItemEvent; |  | ||||||
| import org.bukkit.inventory.ItemStack; |  | ||||||
| import org.bukkit.inventory.meta.ItemMeta; |  | ||||||
|  |  | ||||||
| import java.util.Objects; |  | ||||||
|  |  | ||||||
| public class CraftPixelBlockListener implements Listener { |  | ||||||
|     @EventHandler |  | ||||||
|     static void onCraftItem(CraftItemEvent event) { |  | ||||||
|         ItemStack craftedItem = event.getCurrentItem(); |  | ||||||
|         Objects.requireNonNull(craftedItem); |  | ||||||
|  |  | ||||||
|         ItemMeta craftedItemMeta = craftedItem.getItemMeta(); |  | ||||||
|         String itemName = PlainTextComponentSerializer.plainText().serialize(craftedItemMeta.itemName()); |  | ||||||
|  |  | ||||||
|         if(!itemName.equals(PixelBlockItem.unusedBlockID.toString())) return; |  | ||||||
|         if(event.isShiftClick()) event.setCancelled(true); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -17,8 +17,8 @@ public class DiscoverRecipesListener implements Listener { | |||||||
|     public void shouldDiscover(InventoryClickEvent event) { |     public void shouldDiscover(InventoryClickEvent event) { | ||||||
|         ItemStack clickedItem = event.getCurrentItem(); |         ItemStack clickedItem = event.getCurrentItem(); | ||||||
|         if(clickedItem == null) return; |         if(clickedItem == null) return; | ||||||
|         if(!List.of(Material.HEART_OF_THE_SEA, Material.GLOW_BERRIES).contains(clickedItem.getType())) return; |  | ||||||
|         if(!(event.getWhoClicked() instanceof Player player)) return; |         if(!(event.getWhoClicked() instanceof Player player)) return; | ||||||
|  |         if(!List.of(Material.HEART_OF_THE_SEA, Material.END_CRYSTAL).contains(clickedItem.getType())) return; | ||||||
|         if(player.hasDiscoveredRecipe(PixelBlockItem.recipeKey)) return; |         if(player.hasDiscoveredRecipe(PixelBlockItem.recipeKey)) return; | ||||||
|         PixelBlocksPlugin.plugin.getLogger().log(Level.INFO, String.format("%s unlocked tne PixelBlock recipe!", player.getName())); |         PixelBlocksPlugin.plugin.getLogger().log(Level.INFO, String.format("%s unlocked tne PixelBlock recipe!", player.getName())); | ||||||
|         player.discoverRecipe(PixelBlockItem.recipeKey); |         player.discoverRecipe(PixelBlockItem.recipeKey); | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock; | |||||||
| import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; | import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld; | ||||||
| import eu.mhsl.minecraft.pixelblocks.utils.Direction; | import eu.mhsl.minecraft.pixelblocks.utils.Direction; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; | import net.kyori.adventure.text.format.NamedTextColor; | ||||||
| import org.bukkit.Location; | import org.bukkit.Location; | ||||||
| import org.bukkit.Material; | import org.bukkit.Material; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| @@ -14,7 +14,6 @@ import org.bukkit.event.EventHandler; | |||||||
| import org.bukkit.event.Listener; | import org.bukkit.event.Listener; | ||||||
| import org.bukkit.event.block.BlockPlaceEvent; | import org.bukkit.event.block.BlockPlaceEvent; | ||||||
| import org.bukkit.inventory.ItemStack; | import org.bukkit.inventory.ItemStack; | ||||||
| import org.bukkit.inventory.meta.ItemMeta; |  | ||||||
|  |  | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  |  | ||||||
| @@ -22,15 +21,12 @@ public class PlacePixelBlockListener implements Listener { | |||||||
|     @EventHandler |     @EventHandler | ||||||
|     static void onBlockPlace(BlockPlaceEvent event) { |     static void onBlockPlace(BlockPlaceEvent event) { | ||||||
|         ItemStack usedItem = event.getItemInHand(); |         ItemStack usedItem = event.getItemInHand(); | ||||||
|         ItemMeta usedItemMeta = usedItem.getItemMeta(); |         PixelBlockItem.BlockInfo info = PixelBlockItem.getBlockInfo(usedItem); | ||||||
|         Component displayName = usedItemMeta.displayName(); |         if(info == null) return; | ||||||
|         if(displayName == null) return; |  | ||||||
|         if(!displayName.toString().contains("Pixelblock")) return; |  | ||||||
|         if(!usedItemMeta.getEnchantmentGlintOverride()) return; |  | ||||||
|  |  | ||||||
|         World playerWorld = event.getPlayer().getWorld(); |         World playerWorld = event.getPlayer().getWorld(); | ||||||
|         if(PixelBlockWorld.isPixelWorld(playerWorld)) { |         if(PixelBlockWorld.isPixelWorld(playerWorld)) { | ||||||
|             event.getPlayer().sendMessage("In Pixelblöcken kann kein Pixelblock erstellt werden."); |             event.getPlayer().sendMessage(Component.text("In Pixelblöcken kann kein Pixelblock platziert werden.", NamedTextColor.RED)); | ||||||
|             event.setCancelled(true); |             event.setCancelled(true); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -39,10 +35,9 @@ public class PlacePixelBlockListener implements Listener { | |||||||
|         playerWorld.getBlockAt(newBlockLocation).setType(Material.AIR); |         playerWorld.getBlockAt(newBlockLocation).setType(Material.AIR); | ||||||
|  |  | ||||||
|         Direction direction = Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()); |         Direction direction = Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()); | ||||||
|         String itemName = PlainTextComponentSerializer.plainText().serialize(usedItemMeta.itemName()); |  | ||||||
|  |  | ||||||
|         PixelBlock pixelBlock; |         PixelBlock pixelBlock; | ||||||
|         if(itemName.equals(PixelBlockItem.unusedBlockID.toString())) { |         if(!info.hasOwner()) { | ||||||
|             pixelBlock = new PixelBlock( |             pixelBlock = new PixelBlock( | ||||||
|                 newBlockLocation, |                 newBlockLocation, | ||||||
|                 event.getPlayer().getUniqueId(), |                 event.getPlayer().getUniqueId(), | ||||||
| @@ -50,7 +45,7 @@ public class PlacePixelBlockListener implements Listener { | |||||||
|                 direction |                 direction | ||||||
|             ); |             ); | ||||||
|         } else { |         } else { | ||||||
|             UUID itemUUID = UUID.fromString(itemName); |             UUID itemUUID = info.id(); | ||||||
|             pixelBlock = PixelBlocksPlugin.pixelBlocks.stream() |             pixelBlock = PixelBlocksPlugin.pixelBlocks.stream() | ||||||
|                 .filter(block -> block.blockUUID.equals(itemUUID)) |                 .filter(block -> block.blockUUID.equals(itemUUID)) | ||||||
|                 .findFirst() |                 .findFirst() | ||||||
|   | |||||||
| @@ -4,6 +4,8 @@ import eu.mhsl.minecraft.pixelblocks.PixelBlockItem; | |||||||
| import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; | import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; | ||||||
| import eu.mhsl.minecraft.pixelblocks.utils.Direction; | import eu.mhsl.minecraft.pixelblocks.utils.Direction; | ||||||
| import eu.mhsl.minecraft.pixelblocks.utils.MinMaxUtil; | import eu.mhsl.minecraft.pixelblocks.utils.MinMaxUtil; | ||||||
|  | import net.kyori.adventure.text.Component; | ||||||
|  | import net.kyori.adventure.text.format.NamedTextColor; | ||||||
| import org.bukkit.*; | import org.bukkit.*; | ||||||
| import org.bukkit.block.data.BlockData; | import org.bukkit.block.data.BlockData; | ||||||
| import org.bukkit.entity.*; | import org.bukkit.entity.*; | ||||||
| @@ -23,7 +25,7 @@ public class PixelBlock { | |||||||
|  |  | ||||||
|     public Location pixelBlockLocation; |     public Location pixelBlockLocation; | ||||||
|     public Direction facingDirection; |     public Direction facingDirection; | ||||||
|     public ArrayList<Pixel> pixels = new ArrayList<>(); |     public List<Pixel> pixels = new ArrayList<>(); | ||||||
|  |  | ||||||
|     public Interaction hitbox; |     public Interaction hitbox; | ||||||
|     public ItemDisplay barrier; |     public ItemDisplay barrier; | ||||||
| @@ -33,6 +35,8 @@ public class PixelBlock { | |||||||
|     public UUID ownerUUID; |     public UUID ownerUUID; | ||||||
|     public UUID blockUUID; |     public UUID blockUUID; | ||||||
|  |  | ||||||
|  |     public static final int maxPixelsPerBlock = 2000; | ||||||
|  |  | ||||||
|     public static @NotNull String getWorldName(@NotNull PixelBlock pixelBlock) { |     public static @NotNull String getWorldName(@NotNull PixelBlock pixelBlock) { | ||||||
|         return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + pixelBlock.blockUUID; |         return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + pixelBlock.blockUUID; | ||||||
|     } |     } | ||||||
| @@ -58,7 +62,7 @@ public class PixelBlock { | |||||||
|         searchLocation.setYaw(0); |         searchLocation.setYaw(0); | ||||||
|  |  | ||||||
|         return PixelBlocksPlugin.pixelBlocks.stream() |         return PixelBlocksPlugin.pixelBlocks.stream() | ||||||
|                 .filter(block -> block.pixelBlockLocation.equals(searchLocation)) |                 .filter(block -> Objects.equals(block.pixelBlockLocation, searchLocation)) | ||||||
|                 .findFirst() |                 .findFirst() | ||||||
|                 .orElse(null); |                 .orElse(null); | ||||||
|     } |     } | ||||||
| @@ -80,7 +84,7 @@ public class PixelBlock { | |||||||
|  |  | ||||||
|     public void enterBlock(@NotNull Player player) { |     public void enterBlock(@NotNull Player player) { | ||||||
|         if(PixelBlocksPlugin.configuration.onlyEditableByOwner() && !player.getUniqueId().equals(ownerUUID)) { |         if(PixelBlocksPlugin.configuration.onlyEditableByOwner() && !player.getUniqueId().equals(ownerUUID)) { | ||||||
|             player.sendMessage("Dieser Pixelblock gehört nicht dir!"); |             player.sendMessage(Component.text("Dieser Pixelblock gehört nicht dir!", NamedTextColor.RED)); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -169,15 +173,18 @@ public class PixelBlock { | |||||||
|                         BlockData block = blockLocation.getBlock().getBlockData(); |                         BlockData block = blockLocation.getBlock().getBlockData(); | ||||||
|  |  | ||||||
|                         if(block.getMaterial() != Material.AIR) { |                         if(block.getMaterial() != Material.AIR) { | ||||||
|                             Pixel newPixel = new Pixel(relativeLocation, block, ((double) 1 /pixelsPerBlock)); |                             pixels.add(new Pixel(relativeLocation, block, ((double) 1/pixelsPerBlock))); | ||||||
|                             pixels.add(newPixel); |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             for(Pixel pixel : this.pixels) { |             this.pixels.stream() | ||||||
|                 pixel.place(this.pixelBlockLocation); |                 .limit(maxPixelsPerBlock) | ||||||
|  |                 .forEach(pixel -> pixel.place(this.pixelBlockLocation)); | ||||||
|  |  | ||||||
|  |             if(this.pixels.size() > maxPixelsPerBlock) { | ||||||
|  |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(this.pixels.size() < 5) { |             if(this.pixels.size() < 5) { | ||||||
| @@ -222,7 +229,7 @@ public class PixelBlock { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         this.pixelWorld.getPlayersInWorld().forEach(p -> { |         this.pixelWorld.getPlayersInWorld().forEach(p -> { | ||||||
|             p.sendMessage("Der Pixelblock wurde von einem anderen Spieler abgebaut."); |             p.sendMessage(Component.text("Der Pixelblock wurde von einem anderen Spieler abgebaut!", NamedTextColor.RED)); | ||||||
|             p.teleport(this.lastEntryLocation); |             p.teleport(this.lastEntryLocation); | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -234,6 +241,7 @@ public class PixelBlock { | |||||||
|         PixelBlocksPlugin.database.deletePixelBlock(this); |         PixelBlocksPlugin.database.deletePixelBlock(this); | ||||||
|         this.pixelBlockLocation.getWorld().playSound(this.pixelBlockLocation, Sound.BLOCK_COPPER_BULB_BREAK, 1.0F, 30); |         this.pixelBlockLocation.getWorld().playSound(this.pixelBlockLocation, Sound.BLOCK_COPPER_BULB_BREAK, 1.0F, 30); | ||||||
|         this.pixelBlockLocation.getWorld().dropItem(this.pixelBlockLocation.add(new Vector(0.5, 0.5, 0.5)), PixelBlockItem.getBlockAsItem(this)); |         this.pixelBlockLocation.getWorld().dropItem(this.pixelBlockLocation.add(new Vector(0.5, 0.5, 0.5)), PixelBlockItem.getBlockAsItem(this)); | ||||||
|  |         this.pixelBlockLocation = null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void clearEntities() { |     private void clearEntities() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user