diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java index 6c9d623..c6be9ab 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/PixelBlockDatabase.java @@ -79,7 +79,7 @@ public class PixelBlockDatabase { this.insertOrReplacePixelBlock.setDouble(5, pixelBlock.getPixelBlockLocation().getY()); this.insertOrReplacePixelBlock.setDouble(6, pixelBlock.getPixelBlockLocation().getZ()); - if (pixelBlock.getLastEntryLocation() != null) { + if (pixelBlock.hasLastEntryLocation()) { this.insertOrReplacePixelBlock.setString(7, pixelBlock.getLastEntryLocation().getWorld().getName()); this.insertOrReplacePixelBlock.setDouble(8, pixelBlock.getLastEntryLocation().getX()); this.insertOrReplacePixelBlock.setDouble(9, pixelBlock.getLastEntryLocation().getY()); diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java index 4138645..b990275 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/Pixel.java @@ -16,7 +16,7 @@ import java.util.Objects; import java.util.UUID; public class Pixel { - private static final NamespacedKey parentBlockTag = new NamespacedKey(Main.plugin, "parent"); + private static final NamespacedKey pixelOfTag = new NamespacedKey(Main.plugin, "pixel_of"); private final @NotNull PixelBlock parentBlock; private final @NotNull BlockDisplay entity; @@ -28,8 +28,8 @@ public class Pixel { public static Pixel existingPixel(PixelBlock parentBlock, BlockDisplay entity) { PersistentDataContainer dataContainer = entity.getPersistentDataContainer(); - if(!dataContainer.has(parentBlockTag)) throw new IllegalArgumentException("Entity is missing the parent tag in the DataContainer"); - UUID expectedParentUuid = UUID.fromString(Objects.requireNonNull(dataContainer.get(parentBlockTag, PersistentDataType.STRING))); + if(!dataContainer.has(pixelOfTag)) throw new IllegalArgumentException("Entity is missing the parent tag in the DataContainer"); + UUID expectedParentUuid = UUID.fromString(Objects.requireNonNull(dataContainer.get(pixelOfTag, PersistentDataType.STRING))); if(!parentBlock.getBlockUUID().equals(expectedParentUuid)) throw new IllegalArgumentException("Pixel is from a different parent block"); return new Pixel(parentBlock, entity); } @@ -57,7 +57,7 @@ public class Pixel { Transformation transform = this.entity.getTransformation(); transform.getScale().set(this.scale); this.entity.setTransformation(transform); - this.entity.getPersistentDataContainer().set(parentBlockTag, PersistentDataType.STRING, this.parentBlock.getBlockUUID().toString()); + this.entity.getPersistentDataContainer().set(pixelOfTag, PersistentDataType.STRING, this.parentBlock.getBlockUUID().toString()); } public void destroy() { diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java index b66ff49..0ad2e11 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlock.java @@ -9,8 +9,6 @@ import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.*; import org.bukkit.block.data.BlockData; import org.bukkit.entity.*; -import org.bukkit.inventory.ItemStack; -import org.bukkit.util.Transformation; import org.bukkit.util.Vector; import org.jetbrains.annotations.NotNull; @@ -23,7 +21,6 @@ import java.util.stream.IntStream; public class PixelBlock { private final PixelBlockWorld pixelWorld; - private final float hitboxOffset = (float) Main.configuration.hitboxOffset(); private final int pixelsPerBlock = Main.configuration.pixelsPerBlock(); private Location pixelBlockLocation; @@ -31,7 +28,7 @@ public class PixelBlock { private final List pixels = new ArrayList<>(); private PixelBlockHitbox hitbox; - private final List placeholderIcon = new ArrayList<>(); + private PixelBlockPlaceholder placeholder; private Location lastEntryLocation; private final UUID ownerUUID; @@ -88,6 +85,11 @@ public class PixelBlock { this.pixels.add(Pixel.existingPixel(this, blockDisplay)); } catch(IllegalArgumentException ignored) {} }); + + this.placeholder = PixelBlockPlaceholder.fromExisting(this); + try { + this.hitbox = PixelBlockHitbox.fromExisting(this); + } catch(NoSuchElementException ignored) {} } public TaskChain getBlockTaskChain() { @@ -119,10 +121,6 @@ public class PixelBlock { this.lastEntryLocation = lastEntryLocation; } - public void spawnInteraction(boolean fullBlock) { - this.hitbox = new PixelBlockHitbox(fullBlock, pixelBlockLocation, hitboxOffset, this.pixels, pixelsPerBlock); - } - public void updateEntities() { record PixelData(PixelBlock parent, Vector relativeLocation, BlockData block, double scale) { Pixel create() { @@ -170,43 +168,7 @@ public class PixelBlock { this.getBlockTaskChain() .sync(() -> { - if(this.pixels.size() < 5) { -// Location relativeLocation = new Location(pixelBlockLocation.getWorld(), 0, 0, 0); -// BlockData block = Material.GRAY_STAINED_GLASS.createBlockData(); -// Pixel newPixel = new Pixel(relativeLocation, block, 1); -// pixels.add(newPixel); -// newPixel.place(this.pixelBlockLocation); - - Location itemDisplayLocation = this.pixelBlockLocation.clone().add(0.5, 0.5, 0.5); - - for(int i = 0; i <= 90; i += 90) { - ItemDisplay verticalEntity = (ItemDisplay) this.pixelBlockLocation.getWorld().spawnEntity( - itemDisplayLocation, - EntityType.ITEM_DISPLAY - ); - verticalEntity.setRotation(i, 0); - this.placeholderIcon.add(verticalEntity); - } - - ItemDisplay horizontalEntity = (ItemDisplay) this.pixelBlockLocation.getWorld().spawnEntity( - itemDisplayLocation, - EntityType.ITEM_DISPLAY - ); - horizontalEntity.setRotation(0, 90); - this.placeholderIcon.add(horizontalEntity); - - this.placeholderIcon.forEach(itemDisplay -> { - itemDisplay.setItemStack(ItemStack.of(Material.END_CRYSTAL)); - Transformation transform = itemDisplay.getTransformation(); - transform.getScale().set(0.5); - itemDisplay.setTransformation(transform); - }); - - spawnInteraction(true); - } else { - spawnInteraction(false); - } - + this.hitbox = PixelBlockHitbox.newHitbox(this); Main.plugin.getLogger().info(String.format("Placed %d entities for PixelBlock '%s'", this.pixels.size(), this.blockUUID)); }) .execute(); @@ -225,6 +187,8 @@ public class PixelBlock { this.facingDirection = direction; updateEntities(); Main.database.savePixelBlock(this); + + this.placeholder = PixelBlockPlaceholder.newPlaceholder(this); } public void destroy(Player destroyedBy) { @@ -267,10 +231,7 @@ public class PixelBlock { this.hitbox = null; } - if(!placeholderIcon.isEmpty()) { - this.placeholderIcon.forEach(Entity::remove); - this.placeholderIcon.clear(); - } + this.placeholder.destroy(); // this.pixelBlockLocation.getWorld().getEntities().stream() // .filter(this::isPixelBlockComponent) @@ -300,18 +261,14 @@ public class PixelBlock { return facingDirection; } + public boolean hasLastEntryLocation() { + return this.lastEntryLocation != null; + } + public List getPixels() { return pixels; } - public PixelBlockHitbox getHitbox() { - return hitbox; - } - - public List getPlaceholderIcon() { - return placeholderIcon; - } - public Location getLastEntryLocation() { return lastEntryLocation.clone(); } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java index c82e446..5535f99 100644 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockHitbox.java @@ -1,23 +1,57 @@ package eu.mhsl.minecraft.pixelblocks.pixelblock; +import eu.mhsl.minecraft.pixelblocks.Main; import eu.mhsl.minecraft.pixelblocks.utils.MinMaxUtil; import org.bukkit.Location; +import org.bukkit.NamespacedKey; import org.bukkit.entity.EntityType; import org.bukkit.entity.Interaction; +import org.bukkit.persistence.PersistentDataType; import java.util.List; +import java.util.Objects; +import java.util.UUID; public class PixelBlockHitbox { - private final Interaction hitbox; + private static final NamespacedKey hitboxOfTag = new NamespacedKey(Main.plugin, "hitbox_of"); - public PixelBlockHitbox(boolean fullBlock, Location pixelBlockLocation, float hitboxOffset, List pixels, int pixelsPerBlock) { - if(fullBlock || true) { - hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity( - pixelBlockLocation.clone().add(0.5, -hitboxOffset, 0.5), + private final Interaction interaction; + + public static PixelBlockHitbox fromExisting(PixelBlock parentBlock) { + Interaction hitBox = parentBlock.getPixelBlockLocation().getNearbyEntitiesByType(Interaction.class, 1) + .stream() + .filter(interaction -> interaction.getPersistentDataContainer().has(hitboxOfTag)) + .filter(interaction -> Objects.equals( + interaction.getPersistentDataContainer().get(hitboxOfTag, PersistentDataType.STRING), + parentBlock.getBlockUUID().toString() + )) + .reduce((a, b) -> { + throw new IllegalStateException(String.format("Mehrere hitboxen für PixelBlock '%s' gefunden!", parentBlock.getBlockUUID())); + }) + .orElseThrow(); + + return new PixelBlockHitbox(hitBox); + } + + public static PixelBlockHitbox newHitbox(PixelBlock parentBlock) { + return new PixelBlockHitbox(parentBlock.getPixelBlockLocation(), parentBlock.getPixels(), parentBlock.getBlockUUID()); + } + + private PixelBlockHitbox(Interaction interaction) { + this.interaction = interaction; + } + + private PixelBlockHitbox(Location pixelBlockLocation, List pixels, UUID parentBlockUUID) { + float offset = (float) Main.configuration.hitboxOffset(); + int pixelsPerBlock = Main.configuration.pixelsPerBlock(); + + if(pixels.size() > 5 || true) { + interaction = (Interaction) pixelBlockLocation.getWorld().spawnEntity( + pixelBlockLocation.clone().add(0.5, -offset, 0.5), EntityType.INTERACTION ); - hitbox.setInteractionHeight(1 + 2*hitboxOffset); - hitbox.setInteractionWidth(1 + 2*hitboxOffset); + interaction.setInteractionHeight(1 + 2*offset); + interaction.setInteractionWidth(1 + 2*offset); } else { double startingX = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.location.getX()); double startingY = MinMaxUtil.getMinProperty(pixels, pixel -> pixel.location.getY()); @@ -29,17 +63,17 @@ public class PixelBlockHitbox { Location spawnLocation = pixelBlockLocation.clone().add( ((startingX+endingX+1)/2)/pixelsPerBlock, - (startingY/pixelsPerBlock)-hitboxOffset, + (startingY/pixelsPerBlock)-offset, ((startingZ+endingZ+1)/2)/pixelsPerBlock ); - float height = (float) (endingY-startingY+1)/pixelsPerBlock + 2*hitboxOffset; + float height = (float) (endingY-startingY+1)/pixelsPerBlock + 2*offset; float width; if((endingX-startingX) > (endingZ-startingZ)) { - width = (float) (endingX-startingX+1)/pixelsPerBlock + 2*hitboxOffset; + width = (float) (endingX-startingX+1)/pixelsPerBlock + 2*offset; } else { - width = (float) (endingZ-startingZ+1)/pixelsPerBlock + 2*hitboxOffset; + width = (float) (endingZ-startingZ+1)/pixelsPerBlock + 2*offset; } if(spawnLocation.getX()+width/2 > pixelBlockLocation.getX()+1) { @@ -56,17 +90,20 @@ public class PixelBlockHitbox { spawnLocation.add(0, 0, pixelBlockLocation.getZ()-(spawnLocation.getZ()-width/2)); } - hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity( + interaction = (Interaction) pixelBlockLocation.getWorld().spawnEntity( spawnLocation, EntityType.INTERACTION ); - hitbox.setInteractionHeight(height); - hitbox.setInteractionWidth(width); + interaction.setInteractionHeight(height); + interaction.setInteractionWidth(width); } + + this.interaction.getPersistentDataContainer() + .set(hitboxOfTag, PersistentDataType.STRING, parentBlockUUID.toString()); } public void remove() { - this.hitbox.remove(); + this.interaction.remove(); } } diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockInteraction.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockInteraction.java deleted file mode 100644 index 19a1863..0000000 --- a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockInteraction.java +++ /dev/null @@ -1,5 +0,0 @@ -package eu.mhsl.minecraft.pixelblocks.pixelblock; - -public class PixelBlockInteraction { - -} diff --git a/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockPlaceholder.java b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockPlaceholder.java new file mode 100644 index 0000000..4822055 --- /dev/null +++ b/src/main/java/eu/mhsl/minecraft/pixelblocks/pixelblock/PixelBlockPlaceholder.java @@ -0,0 +1,91 @@ +package eu.mhsl.minecraft.pixelblocks.pixelblock; + +import eu.mhsl.minecraft.pixelblocks.Main; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.entity.Entity; +import org.bukkit.entity.EntityType; +import org.bukkit.entity.ItemDisplay; +import org.bukkit.inventory.ItemStack; +import org.bukkit.persistence.PersistentDataHolder; +import org.bukkit.persistence.PersistentDataType; +import org.bukkit.util.Transformation; + +import java.util.*; + +public class PixelBlockPlaceholder { + private static final NamespacedKey placeholderOfTag = new NamespacedKey(Main.plugin, "placeholder_of"); + + List placeholders = new ArrayList<>(); + + public static PixelBlockPlaceholder fromExisting(PixelBlock parentBlock) { + List placeholders = parentBlock.getPixelBlockLocation() + .getNearbyEntitiesByType(ItemDisplay.class, 1) + .stream() + .filter(itemDisplay -> itemDisplay.getPersistentDataContainer().has(placeholderOfTag)) + .filter(itemDisplay -> Objects.equals( + itemDisplay.getPersistentDataContainer().get(placeholderOfTag, PersistentDataType.STRING), + parentBlock.getBlockUUID().toString() + )) + .toList(); + + return new PixelBlockPlaceholder(placeholders); + } + + public static PixelBlockPlaceholder newPlaceholder(PixelBlock parentBlock) { + return new PixelBlockPlaceholder(parentBlock.getPixelBlockLocation(), parentBlock.getBlockUUID()); + } + + private PixelBlockPlaceholder(List itemDisplays) { + this.placeholders = itemDisplays; + } + + private PixelBlockPlaceholder(Location pixelBlockLocation, UUID parentBlockUUID) { + World pixelBlockWorld = pixelBlockLocation.getWorld(); + Location itemDisplayLocation = pixelBlockLocation.add(0.5, 0.5, 0.5); + + for(int i = 0; i <= 90; i += 90) { + ItemDisplay verticalCore = (ItemDisplay) pixelBlockWorld.spawnEntity( + itemDisplayLocation, + EntityType.ITEM_DISPLAY + ); + verticalCore.setRotation(i, 0); + this.placeholders.add(verticalCore); + } + + ItemDisplay horizontalCore = (ItemDisplay) pixelBlockWorld.spawnEntity( + itemDisplayLocation, + EntityType.ITEM_DISPLAY + ); + horizontalCore.setRotation(0, 90); + this.placeholders.add(horizontalCore); + + this.placeholders.forEach(coreDisplay -> { + coreDisplay.setItemStack(ItemStack.of(Material.END_CRYSTAL)); + Transformation transform = coreDisplay.getTransformation(); + transform.getScale().set(0.5); + coreDisplay.setTransformation(transform); + }); + + ItemDisplay displayContainer = (ItemDisplay) pixelBlockWorld.spawnEntity( + itemDisplayLocation, + EntityType.ITEM_DISPLAY + ); + displayContainer.setItemStack(ItemStack.of(Material.WHITE_STAINED_GLASS)); + this.placeholders.add(displayContainer); + + this.setDataTags(parentBlockUUID); + } + + private void setDataTags(UUID parentBlockUUID) { + this.placeholders.stream() + .map(PersistentDataHolder::getPersistentDataContainer) + .forEach(container -> container.set(placeholderOfTag, PersistentDataType.STRING, parentBlockUUID.toString())); + } + + public void destroy() { + this.placeholders.forEach(Entity::remove); + } +}