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.ShapedRecipe; | ||||
| 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.Nullable; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Objects; | ||||
| import java.util.Optional; | ||||
| import java.util.UUID; | ||||
|  | ||||
| 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 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) { | ||||
|         String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString()); | ||||
|  | ||||
|         ItemStack itemStack = HeadUtil.getCustomTextureHead(itemTexture); | ||||
|         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.lore(List.of( | ||||
|             Component.text(ownerName + " ist der Besitzer dieses Blocks."), | ||||
|             Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!"), | ||||
|             Component.text(block.blockUUID.toString()).color(NamedTextColor.DARK_GRAY) | ||||
|         )); | ||||
|         meta.setEnchantmentGlintOverride(true); | ||||
|         itemStack.setItemMeta(meta); | ||||
|  | ||||
|         return itemStack; | ||||
| @@ -43,13 +65,13 @@ public class PixelBlockItem { | ||||
|     public static @NotNull ItemStack getEmptyPixelBlock() { | ||||
|         ItemStack item = HeadUtil.getCustomTextureHead(itemTexture); | ||||
|         ItemMeta meta = item.getItemMeta(); | ||||
|         meta.setMaxStackSize(1); | ||||
|         meta.displayName(Component.text("Leerer Pixelblock")); | ||||
|         meta.lore(List.of( | ||||
|             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!") | ||||
|         )); | ||||
|         meta.setEnchantmentGlintOverride(true); | ||||
|         meta.itemName(Component.text(unusedBlockID.toString())); | ||||
|         meta.getPersistentDataContainer().set(idProperty, PersistentDataType.STRING, UUID.randomUUID().toString()); | ||||
|         item.setItemMeta(meta); | ||||
|         return item; | ||||
|     } | ||||
| @@ -61,7 +83,7 @@ public class PixelBlockItem { | ||||
|         recipe.setIngredient('B', Material.DIAMOND_BLOCK); | ||||
|         recipe.setIngredient('C', Material.HEART_OF_THE_SEA); | ||||
|         recipe.setIngredient('D', Material.GRASS_BLOCK); | ||||
|         recipe.setIngredient('E', Material.GLOW_BERRIES); | ||||
|         recipe.setIngredient('E', Material.END_CRYSTAL); | ||||
|         return recipe; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -52,7 +52,6 @@ public final class PixelBlocksPlugin extends JavaPlugin { | ||||
|             new PlacePixelBlockListener(), | ||||
|             new PreventInventorysListener(), | ||||
|             new ExitPixelWorldListener(), | ||||
|             new CraftPixelBlockListener(), | ||||
|             new PreventIllegalBlocksListener(), | ||||
|             new BreakPixelBlockListener(), | ||||
|             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) { | ||||
|         ItemStack clickedItem = event.getCurrentItem(); | ||||
|         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(!List.of(Material.HEART_OF_THE_SEA, Material.END_CRYSTAL).contains(clickedItem.getType())) return; | ||||
|         if(player.hasDiscoveredRecipe(PixelBlockItem.recipeKey)) return; | ||||
|         PixelBlocksPlugin.plugin.getLogger().log(Level.INFO, String.format("%s unlocked tne PixelBlock recipe!", player.getName())); | ||||
|         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.utils.Direction; | ||||
| 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.Material; | ||||
| import org.bukkit.World; | ||||
| @@ -14,7 +14,6 @@ import org.bukkit.event.EventHandler; | ||||
| import org.bukkit.event.Listener; | ||||
| import org.bukkit.event.block.BlockPlaceEvent; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.inventory.meta.ItemMeta; | ||||
|  | ||||
| import java.util.UUID; | ||||
|  | ||||
| @@ -22,15 +21,12 @@ public class PlacePixelBlockListener implements Listener { | ||||
|     @EventHandler | ||||
|     static void onBlockPlace(BlockPlaceEvent event) { | ||||
|         ItemStack usedItem = event.getItemInHand(); | ||||
|         ItemMeta usedItemMeta = usedItem.getItemMeta(); | ||||
|         Component displayName = usedItemMeta.displayName(); | ||||
|         if(displayName == null) return; | ||||
|         if(!displayName.toString().contains("Pixelblock")) return; | ||||
|         if(!usedItemMeta.getEnchantmentGlintOverride()) return; | ||||
|         PixelBlockItem.BlockInfo info = PixelBlockItem.getBlockInfo(usedItem); | ||||
|         if(info == null) return; | ||||
|  | ||||
|         World playerWorld = event.getPlayer().getWorld(); | ||||
|         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); | ||||
|             return; | ||||
|         } | ||||
| @@ -39,10 +35,9 @@ public class PlacePixelBlockListener implements Listener { | ||||
|         playerWorld.getBlockAt(newBlockLocation).setType(Material.AIR); | ||||
|  | ||||
|         Direction direction = Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()); | ||||
|         String itemName = PlainTextComponentSerializer.plainText().serialize(usedItemMeta.itemName()); | ||||
|  | ||||
|         PixelBlock pixelBlock; | ||||
|         if(itemName.equals(PixelBlockItem.unusedBlockID.toString())) { | ||||
|         if(!info.hasOwner()) { | ||||
|             pixelBlock = new PixelBlock( | ||||
|                 newBlockLocation, | ||||
|                 event.getPlayer().getUniqueId(), | ||||
| @@ -50,7 +45,7 @@ public class PlacePixelBlockListener implements Listener { | ||||
|                 direction | ||||
|             ); | ||||
|         } else { | ||||
|             UUID itemUUID = UUID.fromString(itemName); | ||||
|             UUID itemUUID = info.id(); | ||||
|             pixelBlock = PixelBlocksPlugin.pixelBlocks.stream() | ||||
|                 .filter(block -> block.blockUUID.equals(itemUUID)) | ||||
|                 .findFirst() | ||||
|   | ||||
| @@ -4,6 +4,8 @@ import eu.mhsl.minecraft.pixelblocks.PixelBlockItem; | ||||
| import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin; | ||||
| import eu.mhsl.minecraft.pixelblocks.utils.Direction; | ||||
| 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.block.data.BlockData; | ||||
| import org.bukkit.entity.*; | ||||
| @@ -23,7 +25,7 @@ public class PixelBlock { | ||||
|  | ||||
|     public Location pixelBlockLocation; | ||||
|     public Direction facingDirection; | ||||
|     public ArrayList<Pixel> pixels = new ArrayList<>(); | ||||
|     public List<Pixel> pixels = new ArrayList<>(); | ||||
|  | ||||
|     public Interaction hitbox; | ||||
|     public ItemDisplay barrier; | ||||
| @@ -33,6 +35,8 @@ public class PixelBlock { | ||||
|     public UUID ownerUUID; | ||||
|     public UUID blockUUID; | ||||
|  | ||||
|     public static final int maxPixelsPerBlock = 2000; | ||||
|  | ||||
|     public static @NotNull String getWorldName(@NotNull PixelBlock pixelBlock) { | ||||
|         return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + pixelBlock.blockUUID; | ||||
|     } | ||||
| @@ -58,7 +62,7 @@ public class PixelBlock { | ||||
|         searchLocation.setYaw(0); | ||||
|  | ||||
|         return PixelBlocksPlugin.pixelBlocks.stream() | ||||
|                 .filter(block -> block.pixelBlockLocation.equals(searchLocation)) | ||||
|                 .filter(block -> Objects.equals(block.pixelBlockLocation, searchLocation)) | ||||
|                 .findFirst() | ||||
|                 .orElse(null); | ||||
|     } | ||||
| @@ -80,7 +84,7 @@ public class PixelBlock { | ||||
|  | ||||
|     public void enterBlock(@NotNull Player player) { | ||||
|         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; | ||||
|         } | ||||
|  | ||||
| @@ -169,15 +173,18 @@ public class PixelBlock { | ||||
|                         BlockData block = blockLocation.getBlock().getBlockData(); | ||||
|  | ||||
|                         if(block.getMaterial() != Material.AIR) { | ||||
|                             Pixel newPixel = new Pixel(relativeLocation, block, ((double) 1 /pixelsPerBlock)); | ||||
|                             pixels.add(newPixel); | ||||
|                             pixels.add(new Pixel(relativeLocation, block, ((double) 1/pixelsPerBlock))); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             for(Pixel pixel : this.pixels) { | ||||
|                 pixel.place(this.pixelBlockLocation); | ||||
|             this.pixels.stream() | ||||
|                 .limit(maxPixelsPerBlock) | ||||
|                 .forEach(pixel -> pixel.place(this.pixelBlockLocation)); | ||||
|  | ||||
|             if(this.pixels.size() > maxPixelsPerBlock) { | ||||
|  | ||||
|             } | ||||
|  | ||||
|             if(this.pixels.size() < 5) { | ||||
| @@ -222,7 +229,7 @@ public class PixelBlock { | ||||
|         } | ||||
|  | ||||
|         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); | ||||
|         }); | ||||
|  | ||||
| @@ -234,6 +241,7 @@ public class PixelBlock { | ||||
|         PixelBlocksPlugin.database.deletePixelBlock(this); | ||||
|         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 = null; | ||||
|     } | ||||
|  | ||||
|     private void clearEntities() { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user