wip: further code cleanup

This commit is contained in:
Elias Müller 2024-07-23 22:25:00 +02:00
parent e5e1f39989
commit 93dc9d8a80
25 changed files with 556 additions and 407 deletions

View File

@ -6,18 +6,14 @@ import org.jetbrains.annotations.NotNull;
public record PixelBlockConfiguration(
int pixelsPerBlock,
boolean liveUpdate,
int worldGrassBorderWidth,
double hitboxOffset,
boolean deleteOnBreak, // TODO does no longer exists
boolean onlyBreakableByOwner,
boolean onlyEditableByOwner
) {
public static void setDefaults(FileConfiguration config) {
config.addDefault(Keys.PixelsPerBlock.key, 16);
config.addDefault(Keys.LiveUpdate.key, true);
config.addDefault(Keys.WorldGrassBorderWidth.key, 5);
config.addDefault(Keys.HitboxOffset.key, 0.005);
config.addDefault(Keys.DeleteOnBreak.key, false);
config.addDefault(Keys.OnlyBreakableByOwners.key, false);
config.addDefault(Keys.OnlyEditableByOwners.key, true);
config.options().copyDefaults(true);
@ -26,9 +22,7 @@ public record PixelBlockConfiguration(
public enum Keys {
PixelsPerBlock("pixelsPerBlock"),
LiveUpdate("liveUpdate"),
WorldGrassBorderWidth("worldGrassBorderWidth"),
HitboxOffset("hitboxOffset"),
DeleteOnBreak("deleteOnBreak"),
OnlyBreakableByOwners("onlyBreakableByOwners"),
OnlyEditableByOwners("onlyEditableByOwners");

View File

@ -4,8 +4,6 @@ import eu.mhsl.minecraft.pixelblocks.utils.Direction;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import java.sql.*;
import java.util.ArrayList;
@ -13,194 +11,182 @@ import java.util.List;
import java.util.UUID;
public class PixelBlockDatabase {
public Connection db;
private final Connection db;
private final PreparedStatement getAllPixelBlocks;
private final PreparedStatement deletePixelBlock;
private final PreparedStatement insertNewPixelBlock;
private final PreparedStatement updateExistingPixelBlock;
public PixelBlockDatabase(String url) {
try {
Class.forName("org.sqlite.JDBC");
this.db = DriverManager.getConnection(url);
} catch (SQLException e) {
this.db.createStatement().execute(
"CREATE TABLE IF NOT EXISTS pixelblocks (" +
"uuid CHAR(36) PRIMARY KEY, " +
"owner CHAR(36), " +
"locationWorldName CHAR(36), " +
"locationX DOUBLE, " +
"locationY DOUBLE, " +
"locationZ DOUBLE, " +
"entryLocationWorldName CHAR(36), " +
"entryLocationX DOUBLE, " +
"entryLocationY DOUBLE, " +
"entryLocationZ DOUBLE, " +
"direction CHAR(36)" +
")"
);
this.deletePixelBlock = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?");
this.getAllPixelBlocks = this.db.prepareStatement("SELECT * FROM pixelblocks");
this.insertNewPixelBlock = this.db.prepareStatement(
"INSERT INTO pixelblocks(uuid, owner, " +
"locationWorldName, locationX, locationY, locationZ, " +
"entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"
);
this.updateExistingPixelBlock = this.db.prepareStatement(
"UPDATE pixelblocks " +
"SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," +
"entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " +
"WHERE uuid=?;"
);
} catch (SQLException | RuntimeException | ClassNotFoundException e) {
throw new RuntimeException("Failed to load Database", e);
}
}
public Statement getStatement() throws SQLException {
return this.db.createStatement();
public void close() throws SQLException {
deletePixelBlock.close();
getAllPixelBlocks.close();
insertNewPixelBlock.close();
updateExistingPixelBlock.close();
db.close();
}
public void removePixelBlock(PixelBlock pixelBlock) {
Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
public void deletePixelBlock(PixelBlock pixelBlock) {
Bukkit.getScheduler().runTaskAsynchronously(PixelBlocksPlugin.plugin, () -> {
try {
PreparedStatement prep = this.db.prepareStatement("DELETE FROM pixelblocks WHERE uuid = ?");
prep.setString(1, pixelBlock.blockUUID.toString());
prep.executeUpdate();
prep.close();
this.deletePixelBlock.setString(1, pixelBlock.blockUUID.toString());
this.deletePixelBlock.executeUpdate();
PixelBlocksPlugin.plugin.getLogger().info("DB: Deleted PixelBlock: " + pixelBlock.blockUUID);
} catch (SQLException e) {
System.err.println(e.getMessage());
throw new RuntimeException("Failed to delete PixelBlock", e);
}
});
}
public void savePixelBlock(PixelBlock pixelBlock) {
Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
List<UUID> uuids = new ArrayList<>();
List<UUID> storedPixelBlocks = new ArrayList<>();
try (var statement = getStatement()) {
ResultSet pixelBlocksResult = statement.executeQuery("SELECT * FROM pixelblocks;");
try {
ResultSet pixelBlocksResult = this.getAllPixelBlocks.executeQuery();
while (pixelBlocksResult.next()) {
uuids.add(UUID.fromString(pixelBlocksResult.getString("uuid")));
storedPixelBlocks.add(UUID.fromString(pixelBlocksResult.getString("uuid")));
}
} catch (SQLException e) {
System.err.println(e.getMessage());
throw new RuntimeException("Failed to fetch PixelBlock list", e);
}
if(!uuids.contains(pixelBlock.blockUUID)) {
if(!storedPixelBlocks.contains(pixelBlock.blockUUID)) {
// create new entry if it does not exist
try {
PreparedStatement prep = this.db.prepareStatement(
"INSERT INTO pixelblocks(uuid, owner, " +
"locationWorldName, locationX, locationY, locationZ, " +
"entryLocationWorldName, entryLocationX, entryLocationY, entryLocationZ, direction) " +
"VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
);
prep.setString(1, pixelBlock.blockUUID.toString());
prep.setString(2, pixelBlock.ownerUUID.toString());
this.insertNewPixelBlock.setString(1, pixelBlock.blockUUID.toString());
this.insertNewPixelBlock.setString(2, pixelBlock.ownerUUID.toString());
prep.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName());
prep.setDouble(4, pixelBlock.pixelBlockLocation.getX());
prep.setDouble(5, pixelBlock.pixelBlockLocation.getY());
prep.setDouble(6, pixelBlock.pixelBlockLocation.getZ());
this.insertNewPixelBlock.setString(3, pixelBlock.pixelBlockLocation.getWorld().getName());
this.insertNewPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getX());
this.insertNewPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getY());
this.insertNewPixelBlock.setDouble(6, pixelBlock.pixelBlockLocation.getZ());
if(pixelBlock.lastEntryLocation != null) {
prep.setString(7, pixelBlock.lastEntryLocation.getWorld().getName());
prep.setDouble(8, pixelBlock.lastEntryLocation.getX());
prep.setDouble(9, pixelBlock.lastEntryLocation.getY());
prep.setDouble(10, pixelBlock.lastEntryLocation.getZ());
this.insertNewPixelBlock.setString(7, pixelBlock.lastEntryLocation.getWorld().getName());
this.insertNewPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getX());
this.insertNewPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getY());
this.insertNewPixelBlock.setDouble(10, pixelBlock.lastEntryLocation.getZ());
} else {
prep.setString(7, Bukkit.getWorlds().getFirst().getName());
prep.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getX());
prep.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getY());
prep.setDouble(10, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ());
this.insertNewPixelBlock.setString(7, Bukkit.getWorlds().getFirst().getName());
this.insertNewPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getX());
this.insertNewPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getY());
this.insertNewPixelBlock.setDouble(10, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ());
}
prep.setString(11, pixelBlock.facingDirection.toString());
this.insertNewPixelBlock.setString(11, pixelBlock.facingDirection.toString());
prep.executeUpdate();
prep.close();
this.insertNewPixelBlock.executeUpdate();
PixelBlocksPlugin.plugin.getLogger().info("DB: Created PixelBlock: " + pixelBlock.blockUUID);
} catch (SQLException e) {
System.err.println(e.getMessage());
throw new RuntimeException("Failed to save PixelBlock", e);
}
} else {
// update existing entry
try {
PreparedStatement prep = this.db.prepareStatement(
"UPDATE pixelblocks " +
"SET owner=?, locationWorldName=?, locationX=?, locationY=?, locationZ=?," +
"entryLocationWorldName=?, entryLocationX=?, entryLocationY=?, entryLocationZ=?, direction=? " +
"WHERE uuid=?;"
);
prep.setString(1, pixelBlock.ownerUUID.toString());
this.updateExistingPixelBlock.setString(1, pixelBlock.ownerUUID.toString());
prep.setString(2, pixelBlock.pixelBlockLocation.getWorld().getName());
prep.setDouble(3, pixelBlock.pixelBlockLocation.getX());
prep.setDouble(4, pixelBlock.pixelBlockLocation.getY());
prep.setDouble(5, pixelBlock.pixelBlockLocation.getZ());
this.updateExistingPixelBlock.setString(2, pixelBlock.pixelBlockLocation.getWorld().getName());
this.updateExistingPixelBlock.setDouble(3, pixelBlock.pixelBlockLocation.getX());
this.updateExistingPixelBlock.setDouble(4, pixelBlock.pixelBlockLocation.getY());
this.updateExistingPixelBlock.setDouble(5, pixelBlock.pixelBlockLocation.getZ());
if(pixelBlock.lastEntryLocation != null) {
prep.setString(6, pixelBlock.lastEntryLocation.getWorld().getName());
prep.setDouble(7, pixelBlock.lastEntryLocation.getX());
prep.setDouble(8, pixelBlock.lastEntryLocation.getY());
prep.setDouble(9, pixelBlock.lastEntryLocation.getZ());
this.updateExistingPixelBlock.setString(6, pixelBlock.lastEntryLocation.getWorld().getName());
this.updateExistingPixelBlock.setDouble(7, pixelBlock.lastEntryLocation.getX());
this.updateExistingPixelBlock.setDouble(8, pixelBlock.lastEntryLocation.getY());
this.updateExistingPixelBlock.setDouble(9, pixelBlock.lastEntryLocation.getZ());
} else {
prep.setString(6, Bukkit.getWorlds().getFirst().getName());
prep.setDouble(7, Bukkit.getWorlds().getFirst().getSpawnLocation().getX());
prep.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getY());
prep.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ());
this.updateExistingPixelBlock.setString(6, Bukkit.getWorlds().getFirst().getName());
this.updateExistingPixelBlock.setDouble(7, Bukkit.getWorlds().getFirst().getSpawnLocation().getX());
this.updateExistingPixelBlock.setDouble(8, Bukkit.getWorlds().getFirst().getSpawnLocation().getY());
this.updateExistingPixelBlock.setDouble(9, Bukkit.getWorlds().getFirst().getSpawnLocation().getZ());
}
prep.setString(10, pixelBlock.blockUUID.toString());
prep.setString(11, pixelBlock.facingDirection.toString());
this.updateExistingPixelBlock.setString(10, pixelBlock.blockUUID.toString());
this.updateExistingPixelBlock.setString(11, pixelBlock.facingDirection.toString());
prep.executeUpdate();
prep.close();
this.updateExistingPixelBlock.executeUpdate();
PixelBlocksPlugin.plugin.getLogger().info("DB: Updated PixelBlock: " + pixelBlock.blockUUID);
} catch (SQLException e) {
System.err.println(e.getMessage());
throw new RuntimeException("Failed updating PixelBlock", e);
}
}
});
}
public void loadPixelBlocks() {
List<Entity> entities = new ArrayList<>();
entities.addAll(Bukkit.getWorlds().get(0).getEntities().stream()
.filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY))
.toList());
entities.addAll(Bukkit.getWorlds().get(1).getEntities().stream()
.filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY))
.toList());
entities.addAll(Bukkit.getWorlds().get(2).getEntities().stream()
.filter(entity -> entity.getType().equals(EntityType.BLOCK_DISPLAY) || entity.getType().equals(EntityType.INTERACTION) || entity.getType().equals(EntityType.ITEM_DISPLAY))
.toList());
try {
ResultSet allPixelBlocks = this.getAllPixelBlocks.executeQuery();
String sql = "CREATE TABLE IF NOT EXISTS pixelblocks (" +
"uuid CHAR(36) PRIMARY KEY, " +
"owner CHAR(36), " +
"locationWorldName CHAR(36), " +
"locationX DOUBLE, " +
"locationY DOUBLE, " +
"locationZ DOUBLE, " +
"entryLocationWorldName CHAR(36), " +
"entryLocationX DOUBLE, " +
"entryLocationY DOUBLE, " +
"entryLocationZ DOUBLE, " +
"direction CHAR(36)" +
");";
try (var statement = getStatement()) {
statement.execute(sql);
ResultSet pixelBlocksResult = statement.executeQuery("SELECT * FROM pixelblocks;");
while (pixelBlocksResult.next()) {
Location newPixelBlockLocation = new Location(
Bukkit.getWorld(pixelBlocksResult.getString("locationWorldName")),
pixelBlocksResult.getDouble("locationX"),
pixelBlocksResult.getDouble("locationY"),
pixelBlocksResult.getDouble("locationZ")
while (allPixelBlocks.next()) {
Location blockLocation = new Location(
Bukkit.getWorld(allPixelBlocks.getString("locationWorldName")),
allPixelBlocks.getDouble("locationX"),
allPixelBlocks.getDouble("locationY"),
allPixelBlocks.getDouble("locationZ")
);
Location newEntryLocation = new Location(
Bukkit.getWorld(pixelBlocksResult.getString("entryLocationWorldName")),
pixelBlocksResult.getDouble("entryLocationX"),
pixelBlocksResult.getDouble("entryLocationY"),
pixelBlocksResult.getDouble("entryLocationZ")
Location entryLocation = new Location(
Bukkit.getWorld(allPixelBlocks.getString("entryLocationWorldName")),
allPixelBlocks.getDouble("entryLocationX"),
allPixelBlocks.getDouble("entryLocationY"),
allPixelBlocks.getDouble("entryLocationZ")
);
if(!newPixelBlockLocation.getChunk().isEntitiesLoaded()) {
newPixelBlockLocation.getChunk().load(true);
newPixelBlockLocation.getChunk().getEntities();
}
entities.stream().filter(entity -> entity
.getLocation()
.add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0)
.toBlockLocation()
.equals(newPixelBlockLocation))
.forEach(Entity::remove);
PixelBlock newPixelBlock = new PixelBlock(
newPixelBlockLocation,
UUID.fromString(pixelBlocksResult.getString("owner")),
UUID.fromString(pixelBlocksResult.getString("uuid"))
PixelBlock block = new PixelBlock(
blockLocation,
UUID.fromString(allPixelBlocks.getString("owner")),
UUID.fromString(allPixelBlocks.getString("uuid")),
Direction.valueOf(allPixelBlocks.getString("direction"))
);
newPixelBlock.lastEntryLocation = newEntryLocation;
newPixelBlock.place(newPixelBlockLocation, Direction.valueOf(pixelBlocksResult.getString("direction")));
block.setLastEntryLocation(entryLocation);
PixelBlocksPlugin.plugin.getLogger().info("DB: Loaded PixelBlock: " + block.blockUUID);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
throw new RuntimeException("Failed loading PixelBlocks", e);
}
}
}

View File

@ -2,6 +2,7 @@ package eu.mhsl.minecraft.pixelblocks;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@ -11,16 +12,28 @@ import org.bukkit.inventory.ShapedRecipe;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
public class PixelBlockItem {
public static UUID unusedBlockID = UUID.fromString("98fdf0ae-c3ab-4ef7-ae25-efd518d600de");
public static @NotNull ItemStack getBlockAsItem(@NotNull PixelBlock block) {
ItemStack itemStack = ItemStack.of(Material.GRAY_STAINED_GLASS);
return PixelBlockItem.updateBlockAsItem(block, ItemStack.of(Material.GRAY_STAINED_GLASS));
}
public static @NotNull ItemStack updateBlockAsItem(@NotNull PixelBlock block, @NotNull ItemStack itemStack) {
String ownerName = Optional.ofNullable(Bukkit.getOfflinePlayer(block.ownerUUID).getName()).orElseGet(() -> block.ownerUUID.toString());
ItemMeta meta = itemStack.getItemMeta();
meta.itemName(Component.text(block.blockUUID.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);
@ -31,8 +44,12 @@ public class PixelBlockItem {
ItemStack item = ItemStack.of(Material.GRAY_STAINED_GLASS);
ItemMeta meta = item.getItemMeta();
meta.displayName(Component.text("Leerer Pixelblock"));
meta.lore(List.of(
Component.text("Der erste Spieler, welcher den Block platziert wird der Besitzer des Blocks."),
Component.text("Klicke auf den gesetzten Block, um diesen zu bearbeiten!")
));
meta.setEnchantmentGlintOverride(true);
meta.itemName(Component.text("Pixelblock"));
meta.itemName(Component.text(unusedBlockID.toString()));
item.setItemMeta(meta);
return item;
}

View File

@ -9,6 +9,8 @@ import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@ -18,7 +20,7 @@ public final class PixelBlocksPlugin extends JavaPlugin {
public static PixelBlockConfiguration configuration;
public static PixelBlockDatabase database;
public static List<PixelBlock> placedPixelBlocks = new ArrayList<>();
public static List<PixelBlock> pixelBlocks = new ArrayList<>();
@Override
public void onLoad() {
@ -31,14 +33,13 @@ public final class PixelBlocksPlugin extends JavaPlugin {
PixelBlocksPlugin.configuration = new PixelBlockConfiguration(
config.getInt(PixelBlockConfiguration.Keys.PixelsPerBlock.getKey()),
config.getBoolean(PixelBlockConfiguration.Keys.LiveUpdate.getKey()),
config.getInt(PixelBlockConfiguration.Keys.WorldGrassBorderWidth.getKey()),
config.getDouble(PixelBlockConfiguration.Keys.HitboxOffset.getKey()),
config.getBoolean(PixelBlockConfiguration.Keys.DeleteOnBreak.getKey()),
config.getBoolean(PixelBlockConfiguration.Keys.OnlyBreakableByOwners.getKey()),
config.getBoolean(PixelBlockConfiguration.Keys.OnlyEditableByOwners.getKey())
);
PixelBlocksPlugin.database = new PixelBlockDatabase("jdbc:sqlite:pixelblocks.db");
File databaseFile = new File(plugin.getDataFolder(), "blocks.db");
PixelBlocksPlugin.database = new PixelBlockDatabase("jdbc:sqlite:" + databaseFile);
}
@Override
@ -46,14 +47,16 @@ public final class PixelBlocksPlugin extends JavaPlugin {
database.loadPixelBlocks();
Listener[] listeners = {
new PlayerInteractListener(),
new PlayerMoveListener(),
// new BlockBreakListener(),
new BlockPlaceListener(),
new InventoryListener(),
new PlayerChangeWorldListener(),
new CraftItemListener(),
new InPixelWorldCancelListener()
new EnterPixelBlockListener(),
new FallOutOfPixelBlockListener(),
new BreakPixelListener(),
new PlacePixelBlockListener(),
new PixelWorldInventoryListener(),
new PixelWorldExitListener(),
new CraftPixelBlockListener(),
new PixelWorldBehaviourListener(),
new BreakPixelBlockListener(),
new PlacePixelListener()
};
for (Listener listener : listeners) {
@ -65,4 +68,13 @@ public final class PixelBlocksPlugin extends JavaPlugin {
Bukkit.addRecipe(PixelBlockItem.getRecipe());
}
@Override
public void onDisable() {
try {
database.close();
} catch (SQLException e) {
throw new RuntimeException("Failed disabling", e);
}
}
}

View File

@ -1,15 +0,0 @@
package eu.mhsl.minecraft.pixelblocks.chunkGenerators;
import org.bukkit.World;
import org.bukkit.generator.ChunkGenerator;
import javax.annotation.Nonnull;
import java.util.Random;
public class EmptyChunkGenerator extends ChunkGenerator {
@Override
@Nonnull
public ChunkData generateChunkData(@Nonnull World world, @Nonnull Random random, int x, int y, @Nonnull BiomeGrid biome) {
return createChunkData(world);
}
}

View File

@ -1,8 +1,8 @@
package eu.mhsl.minecraft.pixelblocks.commands;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import eu.mhsl.minecraft.pixelblocks.utils.Direction;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.Command;
@ -11,7 +11,6 @@ import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.UUID;
public class CreatePixelBlockCommand implements CommandExecutor {
@ -19,17 +18,20 @@ public class CreatePixelBlockCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(sender instanceof Player p) {
World playerWorld = p.getWorld();
World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1)};
if(Arrays.stream(standardWorlds).toList().contains(playerWorld)) {
Location playerLocation = p.getLocation();
PixelBlock pixelBlock = new PixelBlock(playerLocation, p.getUniqueId(), UUID.randomUUID());
pixelBlock.place(playerLocation, Direction.south);
} else {
p.sendMessage("Du kannst nur in der Overworld oder im Nether Pixelblocks erstellen!");
if(PixelBlockWorld.getPixelBlockWorlds().contains(playerWorld)) {
p.sendMessage("Pixelblöcke können nicht innerhalb anderen Pixelblöcken erstellt werden.");
return true;
}
}
return(true);
Location playerLocation = p.getLocation();
PixelBlock block = new PixelBlock(
playerLocation,
p.getUniqueId(),
UUID.randomUUID(),
Direction.south
);
block.place(playerLocation, Direction.south);
}
return true;
}
}

View File

@ -1,9 +1,7 @@
package eu.mhsl.minecraft.pixelblocks.commands;
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
@ -18,28 +16,15 @@ public class ExitWorldCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
if(sender instanceof Player p) {
World playerWorld = p.getWorld();
World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1), Bukkit.getWorlds().get(2)};
if(!Arrays.stream(standardWorlds).toList().contains(playerWorld)) {
List<PixelBlock> ownedBlocks = PixelBlocksPlugin.placedPixelBlocks.stream()
.filter(pixelBlock -> pixelBlock.ownerUUID.equals(p.getUniqueId()))
.sorted(Comparator.comparing(pixelBlock -> pixelBlock.lastEntryTime))
.toList();
Location newLocation;
if(!ownedBlocks.isEmpty()) {
newLocation = ownedBlocks.getLast().lastEntryLocation;
} else {
newLocation = Bukkit.getWorlds().getFirst().getSpawnLocation();
}
p.teleport(newLocation);
} else {
p.sendMessage("Dieser Command ist nur für PixelBlock Welten verfügbar!");
if(PixelBlockWorld.getOtherWorlds().contains(playerWorld)) {
p.sendMessage("Du kannst nur Pixelblöcke verlassen.");
return true;
}
}
return(true);
PixelBlock currentPixelBlock = PixelBlock.getPixelBlockFromBlockWorld(playerWorld);
Objects.requireNonNull(currentPixelBlock);
p.teleport(currentPixelBlock.lastEntryLocation);
}
return true;
}
}

View File

@ -1,18 +0,0 @@
//package eu.mhsl.minecraft.pixelblocks.listeners;
//
//import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
//import org.bukkit.event.EventHandler;
//import org.bukkit.event.Listener;
//import org.bukkit.event.block.BlockBreakEvent;
//
//public class BlockBreakListener implements Listener {
// @EventHandler
// static void onBlockBreak(BlockBreakEvent event) {
// if(CommonEventHandlers.isInPixelWorld(event.getBlock().getWorld())) {
// PixelBlock pixelBlock = PixelBlock.getPixelBlockFromWorld(event.getBlock().getLocation().getWorld());
//
// assert pixelBlock != null;
// pixelBlock.handleBlockBreak(event);
// }
// }
//}

View File

@ -1,55 +0,0 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import eu.mhsl.minecraft.pixelblocks.utils.Direction;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Arrays;
import java.util.UUID;
public class BlockPlaceListener implements Listener {
@EventHandler
static void onBlockPlace(BlockPlaceEvent event) {
if(event.getItemInHand().getItemMeta().getDisplayName().contains("Pixelblock")
&& !event.getItemInHand().getItemMeta().getItemName().isEmpty()
&& event.getItemInHand().getItemMeta().getEnchantmentGlintOverride()) {
event.setCancelled(true);
World playerWorld = event.getPlayer().getWorld();
World[] standardWorlds = {Bukkit.getWorlds().get(0), Bukkit.getWorlds().get(1)}; // don't allow Pixelblocks in the end dimension
if(Arrays.stream(standardWorlds).toList().contains(playerWorld)) {
Location newBlockLocation = event.getBlock().getLocation();
if(event.getItemInHand().getItemMeta().getItemName().startsWith("Pixelblock")) {
ItemMeta newMeta = event.getItemInHand().getItemMeta();
newMeta.setItemName(UUID.randomUUID().toString());
event.getItemInHand().setItemMeta(newMeta);
}
PixelBlock pixelBlock = new PixelBlock(newBlockLocation, event.getPlayer().getUniqueId(), UUID.fromString(event.getItemInHand().getItemMeta().getItemName()));
if(pixelBlock.place(newBlockLocation, Direction.vectorToDirection(event.getPlayer().getLocation().getDirection()))) {
event.getPlayer().getInventory().remove(event.getItemInHand());
} else {
event.getPlayer().sendMessage("Hier wurde bereits ein Pixelblock plaziert.");
}
} else {
event.getPlayer().sendMessage("Du kannst nur in der Overworld oder im Nether Pixelblocks platzieren!");
}
} else {
// if(CommonEventHandlers.isInPixelWorld(event.getBlock().getWorld())) {
// PixelBlock pixelBlock = PixelBlock.getPixelBlockFromWorld(event.getBlock().getLocation().getWorld());
//
// assert pixelBlock != null;
// pixelBlock.handleBlockPlace(event);
// }
}
}
}

View File

@ -3,29 +3,14 @@ package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import io.papermc.paper.event.player.PrePlayerAttackEntityEvent;
import org.bukkit.*;
import org.bukkit.Location;
import org.bukkit.entity.Interaction;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class PlayerInteractListener implements Listener {
public class BreakPixelBlockListener implements Listener {
@EventHandler
static void onPlayerInteractEntity(PlayerInteractEntityEvent event) {
if(event.getRightClicked() instanceof Interaction) {
Location interactionLocation = event.getRightClicked().getLocation().clone().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation();
interactionLocation.setYaw(0);
interactionLocation.setPitch(0);
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromPlacedLocation(interactionLocation);
assert pixelBlock != null;
pixelBlock.enterBlock(event.getPlayer());
}
}
@EventHandler
static void onPlayerAttackEntity(PrePlayerAttackEntityEvent event) {
static void destroyPixelBlock(PrePlayerAttackEntityEvent event) {
if(event.getAttacked() instanceof Interaction) {
Location blockLocation = event.getAttacked().getLocation().add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0).toBlockLocation();
blockLocation.setYaw(0);

View File

@ -0,0 +1,27 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import java.util.Objects;
public class BreakPixelListener implements Listener {
@EventHandler
static void onBlockBreak(BlockBreakEvent event) {
World world = event.getBlock().getWorld();
if(!PixelBlockWorld.isPixelWorld(world)) return;
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(world);
Objects.requireNonNull(pixelBlock);
PixelBlockWorld pixelBlockWorld = pixelBlock.getPixelWorld();
Location blockLocation = event.getBlock().getLocation();
if(!pixelBlockWorld.allowPlacements(blockLocation)) event.setCancelled(true);
}
}

View File

@ -1,24 +0,0 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.CraftItemEvent;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.Objects;
import java.util.UUID;
public class CraftItemListener implements Listener {
@EventHandler
static void onCraftItem(CraftItemEvent event) {
if(Objects.requireNonNull(event.getCurrentItem()).getItemMeta().getDisplayName().contains("Pixelblock")) {
if(event.isShiftClick()) {
event.setCancelled(true);
} else {
ItemMeta meta = event.getCurrentItem().getItemMeta();
meta.setItemName("Pixelblock " + UUID.randomUUID());
event.getCurrentItem().setItemMeta(meta);
}
}
}
}

View File

@ -0,0 +1,25 @@
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);
}
}

View File

@ -0,0 +1,30 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.*;
import org.bukkit.entity.Interaction;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerInteractEntityEvent;
public class EnterPixelBlockListener implements Listener {
@EventHandler
static void enterPixelBlock(PlayerInteractEntityEvent event) {
if(event.getRightClicked() instanceof Interaction) {
Location interactionLocation = event
.getRightClicked()
.getLocation()
.add(0, PixelBlocksPlugin.configuration.hitboxOffset(), 0)
.toBlockLocation();
interactionLocation.setYaw(0);
interactionLocation.setPitch(0);
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromPlacedLocation(interactionLocation);
assert pixelBlock != null;
pixelBlock.enterBlock(event.getPlayer());
}
}
}

View File

@ -0,0 +1,23 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.Objects;
public class FallOutOfPixelBlockListener implements Listener {
@EventHandler
static void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
if(player.getLocation().y() > -65) return;
if(!PixelBlockWorld.isPixelWorld(player.getWorld())) return;
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(player.getWorld());
Objects.requireNonNull(pixelBlock);
player.teleport(pixelBlock.getPixelWorld().getSpawnLocation());
}
}

View File

@ -9,7 +9,7 @@ import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerPortalEvent;
public class InPixelWorldCancelListener implements Listener {
public class PixelWorldBehaviourListener implements Listener {
@EventHandler
static void onBlockExplode(BlockExplodeEvent event) {
CommonEventHandlers.cancelIfInPixelWorld(event, event.getBlock().getWorld());

View File

@ -0,0 +1,35 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import org.bukkit.event.player.PlayerPortalEvent;
import java.util.Objects;
public class PixelWorldExitListener implements Listener {
@EventHandler
static void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
World changingFrom = event.getFrom();
if(!PixelBlockWorld.isPixelWorld(changingFrom)) return;
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(changingFrom);
Objects.requireNonNull(pixelBlock);
pixelBlock.updateEntities();
}
@EventHandler
static void onPlayerPortal(PlayerPortalEvent event) {
World pixelBlockWorld = event.getFrom().getWorld();
if(!PixelBlockWorld.isPixelWorld(pixelBlockWorld)) return;
event.setCancelled(true);
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(pixelBlockWorld);
Objects.requireNonNull(pixelBlock);
event.getPlayer().teleport(pixelBlock.lastEntryLocation);
}
}

View File

@ -6,7 +6,7 @@ import org.bukkit.event.inventory.*;
import org.bukkit.inventory.CraftingInventory;
import org.bukkit.inventory.PlayerInventory;
public class InventoryListener implements Listener {
public class PixelWorldInventoryListener implements Listener {
@EventHandler
static void onInventoryOpen(InventoryOpenEvent event) {
if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) {

View File

@ -0,0 +1,72 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.PixelBlockItem;
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
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 org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
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;
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;
World playerWorld = event.getPlayer().getWorld();
if(PixelBlockWorld.isPixelWorld(playerWorld)) {
event.getPlayer().sendMessage("In Pixelblöcken kann kein Pixelblock erstellt werden.");
event.setCancelled(true);
return;
}
Location newBlockLocation = event.getBlock().getLocation();
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())) {
pixelBlock = new PixelBlock(
newBlockLocation,
event.getPlayer().getUniqueId(),
UUID.randomUUID(),
direction
);
} else {
UUID itemUUID = UUID.fromString(itemName);
pixelBlock = PixelBlocksPlugin.pixelBlocks.stream()
.filter(block -> block.blockUUID.equals(itemUUID))
.findFirst()
.orElseGet(() -> new PixelBlock(
newBlockLocation,
event.getPlayer().getUniqueId(),
itemUUID,
direction
));
}
try {
pixelBlock.place(newBlockLocation, direction);
} catch (IllegalArgumentException e) {
event.setCancelled(true);
event.getPlayer().sendMessage(Component.text(e.getMessage()));
}
}
}

View File

@ -0,0 +1,27 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlockWorld;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import java.util.Objects;
public class PlacePixelListener implements Listener {
@EventHandler
static void onBlockPlace(BlockPlaceEvent event) {
World world = event.getBlock().getWorld();
if(!PixelBlockWorld.isPixelWorld(world)) return;
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(world);
Objects.requireNonNull(pixelBlock);
PixelBlockWorld pixelBlockWorld = pixelBlock.getPixelWorld();
Location blockLocation = event.getBlock().getLocation();
if(!pixelBlockWorld.allowPlacements(blockLocation)) event.setCancelled(true);
}
}

View File

@ -1,18 +0,0 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import java.util.Objects;
public class PlayerChangeWorldListener implements Listener {
@EventHandler
static void onPlayerChangeWorld(PlayerChangedWorldEvent event) {
if(CommonEventHandlers.isInPixelWorld(event.getFrom())) {
// Bukkit.getScheduler().runTaskLater(plugin, () -> Objects.requireNonNull(PixelBlock.getPixelBlockFromWorld(event.getFrom())).update(), 60);
Objects.requireNonNull(PixelBlock.getPixelBlockFromBlockWorld(event.getFrom())).update();
}
}
}

View File

@ -1,32 +0,0 @@
package eu.mhsl.minecraft.pixelblocks.listeners;
import eu.mhsl.minecraft.pixelblocks.pixelblock.PixelBlock;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerMoveEvent;
public class PlayerMoveListener implements Listener {
@EventHandler
static void onPlayerMove(PlayerMoveEvent event) {
if(CommonEventHandlers.isInPixelWorld(event.getPlayer().getWorld())) {
Location playerLocation = event.getPlayer().getLocation();
PixelBlock pixelBlock = PixelBlock.getPixelBlockFromBlockWorld(event.getPlayer().getWorld());
assert pixelBlock != null;
Location portalLocation = pixelBlock.getPixelWorld().getPortalLocation().clone();
if(playerLocation.y() < -65) {
event.getPlayer().teleport(pixelBlock.getPixelWorld().getSpawnLocation());
} else if(playerLocation.getZ() < portalLocation.getZ()+1
&& playerLocation.getZ() > portalLocation.getZ()) {
if(playerLocation.getX() < portalLocation.getX()+3
&& playerLocation.getX() > portalLocation.getX()+1) {
if(playerLocation.getY() < portalLocation.getY()+4
&& playerLocation.getY() > portalLocation.getY()+1) {
event.getPlayer().teleport(pixelBlock.lastEntryLocation);
}
}
}
}
}
}

View File

@ -38,7 +38,7 @@ public class PixelBlock {
}
public static @Nullable PixelBlock getPixelBlockFromBlockWorld(World world) {
return PixelBlocksPlugin.placedPixelBlocks.stream()
return PixelBlocksPlugin.pixelBlocks.stream()
.filter(block -> block.blockUUID.equals(getUUIDFromWorld(world)))
.findFirst()
.orElse(null);
@ -57,13 +57,15 @@ public class PixelBlock {
searchLocation.setPitch(0);
searchLocation.setYaw(0);
return PixelBlocksPlugin.placedPixelBlocks.stream()
return PixelBlocksPlugin.pixelBlocks.stream()
.filter(block -> block.pixelBlockLocation.equals(searchLocation))
.findFirst()
.orElse(null);
}
public PixelBlock(Location originLocation, UUID ownerUUID, UUID blockUUID) {
public PixelBlock(Location originLocation, UUID ownerUUID, UUID blockUUID, Direction direction) {
PixelBlocksPlugin.pixelBlocks.add(this);
this.ownerUUID = ownerUUID;
this.blockUUID = blockUUID;
@ -71,7 +73,7 @@ public class PixelBlock {
this.pixelBlockLocation.setYaw(0);
this.pixelBlockLocation.setPitch(0);
this.facingDirection = Direction.south; // TODO ??
this.facingDirection = direction;
this.pixelWorld = new PixelBlockWorld(this);
}
@ -89,6 +91,10 @@ public class PixelBlock {
player.teleport(this.pixelWorld.getSpawnLocation());
}
public void setLastEntryLocation(Location lastEntryLocation) {
this.lastEntryLocation = lastEntryLocation;
}
public void spawnInteraction(boolean fullBlock) {
if(fullBlock) {
hitbox = (Interaction) pixelBlockLocation.getWorld().spawnEntity(
@ -145,7 +151,7 @@ public class PixelBlock {
}
}
public void update() {
public void updateEntities() {
Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
this.clearEntities();
@ -195,20 +201,18 @@ public class PixelBlock {
});
}
public boolean place(Location placeLocation, Direction direction) {
public void place(Location placeLocation, Direction direction) {
Location newLocation = placeLocation.toBlockLocation();
newLocation.setPitch(0);
newLocation.setYaw(0);
if(PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == null || PixelBlock.getPixelBlockFromPlacedLocation(newLocation) == this) {
this.pixelBlockLocation = newLocation;
this.facingDirection = direction;
update();
PixelBlocksPlugin.database.savePixelBlock(this);
PixelBlocksPlugin.placedPixelBlocks.add(this);
return true;
}
return false;
@Nullable PixelBlock blockAtLocation = PixelBlock.getPixelBlockFromPlacedLocation(newLocation);
if(blockAtLocation != null && blockAtLocation != this) throw new IllegalArgumentException("Es können nicht mehrere Pixelblöcke ineinander platziert werden.");
this.pixelBlockLocation = newLocation;
this.facingDirection = direction;
updateEntities();
PixelBlocksPlugin.database.savePixelBlock(this);
}
public void destroy(Player destroyedBy) {
@ -218,15 +222,16 @@ public class PixelBlock {
}
this.pixelWorld.getPlayersInWorld().forEach(p -> {
p.sendMessage("Der Pixelblock wurde abgebaut!");
p.sendMessage("Der Pixelblock wurde von einem anderen Spieler abgebaut.");
p.teleport(this.lastEntryLocation);
});
this.pixelWorld.getEntitiesInWorld().forEach(entity -> entity.teleport(this.lastEntryLocation));
this.pixelWorld.getEntitiesInWorld().stream()
.filter(entity -> entity instanceof Item)
.forEach(entity -> entity.teleport(this.lastEntryLocation));
this.clearEntities();
PixelBlocksPlugin.database.removePixelBlock(this);
PixelBlocksPlugin.placedPixelBlocks.remove(this);
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));
}
@ -267,7 +272,11 @@ public class PixelBlock {
}
public PixelBlockWorld getPixelWorld() {
public @NotNull PixelBlockWorld getPixelWorld() {
return pixelWorld;
}
public int getPixelsPerBlock() {
return pixelsPerBlock;
}
}

View File

@ -1,15 +1,17 @@
package eu.mhsl.minecraft.pixelblocks.pixelblock;
import eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin;
import eu.mhsl.minecraft.pixelblocks.chunkGenerators.EmptyChunkGenerator;
import eu.mhsl.minecraft.pixelblocks.utils.LocationUtil;
import org.bukkit.*;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.generator.ChunkGenerator;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import static eu.mhsl.minecraft.pixelblocks.PixelBlocksPlugin.plugin;
@ -17,7 +19,7 @@ public class PixelBlockWorld {
private final PixelBlock parentPixelBlock;
private final World world;
int worldGrassBorderWidth = PixelBlocksPlugin.configuration.worldGrassBorderWidth();
int worldGrassBorderWidth = 10;
int pixelsPerBlock = PixelBlocksPlugin.configuration.pixelsPerBlock();
public static boolean isPixelWorld(@NotNull World world) {
@ -38,8 +40,16 @@ public class PixelBlockWorld {
this.setBuildingPlatform();
}
public boolean allowPlacements(Location blockLocation) {
Location origin = getBuildOrigin();
int offset = pixelsPerBlock - 1;
return blockLocation.x() >= origin.x() && blockLocation.x() <= origin.x() + offset
&& blockLocation.z() >= origin.z() && blockLocation.z() <= origin.z() + offset
&& blockLocation.y() >= origin.y() && blockLocation.y() <= origin.y() + offset;
}
public @NotNull String getWorldPathName() {
return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + this.parentPixelBlock.blockUUID;
return PixelBlocksPlugin.plugin.getDataFolder().getPath() + File.separator + "worlds" + File.separator + this.parentPixelBlock.blockUUID;
}
public @NotNull Location getSpawnLocation() {
@ -47,7 +57,7 @@ public class PixelBlockWorld {
}
public @NotNull Location getPortalLocation() {
return this.getBuildOrigin().add((double) pixelsPerBlock/2 -2, 0, -worldGrassBorderWidth);
return this.getBuildOrigin().add((double) pixelsPerBlock/2 -2, 0, -worldGrassBorderWidth+3);
}
public @NotNull List<Player> getPlayersInWorld() {
@ -62,11 +72,27 @@ public class PixelBlockWorld {
return new Location(this.world, 0, -60, 0);
}
public @NotNull Location getBuildOriginEnd() {
return getBuildOrigin().add(pixelsPerBlock, pixelsPerBlock, pixelsPerBlock);
}
public @NotNull Location getBorderOrigin() {
return getBuildOrigin().subtract(1, 1, 1);
}
public @NotNull Location getPlatformOrigin() {
return getBorderOrigin().subtract(worldGrassBorderWidth, 0, worldGrassBorderWidth);
}
public @NotNull Location getPlatformOriginEnd() {
return getBorderOrigin().add(worldGrassBorderWidth + pixelsPerBlock, 0, worldGrassBorderWidth + pixelsPerBlock);
}
private World loadOrCreatePixelWorld() {
final WorldCreator worldCreator = new WorldCreator(getWorldPathName());
worldCreator.type(WorldType.FLAT);
worldCreator.generator(new EmptyChunkGenerator());
worldCreator.generator(new ChunkGenerator() {});
World world = Bukkit.createWorld(worldCreator);
Objects.requireNonNull(world);
@ -78,45 +104,71 @@ public class PixelBlockWorld {
world.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
WorldBorder worldBorder = world.getWorldBorder();
worldBorder.setCenter(getBuildOrigin());
worldBorder.setCenter(getBuildOrigin().add((double) pixelsPerBlock / 2, 0, (double) pixelsPerBlock / 2));
worldBorder.setSize(pixelsPerBlock + (2*worldGrassBorderWidth));
worldBorder.setWarningDistance(0);
worldBorder.setDamageAmount(0);
return world;
}
private void setBuildingPlatform() {
Location borderStartLocation = getBuildOrigin().subtract(1, 1, 1);
Location grassStartLocation = borderStartLocation.clone().subtract(worldGrassBorderWidth, 0, worldGrassBorderWidth);
Bukkit.getScheduler().runTask(PixelBlocksPlugin.plugin, () -> {
for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) {
for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) {
grassStartLocation.clone().add(x, 0, z).getBlock().setType(Material.GRASS_BLOCK);
getPlatformOrigin().add(x, 0, z).getBlock().setType(Material.GRASS_BLOCK);
}
}
for (int x = 0; x < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; x++) {
for (int z = 0; z < (pixelsPerBlock+2) + 2 * worldGrassBorderWidth; z++) {
grassStartLocation.clone().add(x, -1, z).getBlock().setType(Material.DIRT);
getPlatformOrigin().add(x, -1, z).getBlock().setType(Material.DIRT);
}
}
for (int x = 0; x < (pixelsPerBlock+2); x++) {
for (int z = 0; z < (pixelsPerBlock+2); z++) {
Location currentLocation = borderStartLocation.clone().add(x, 0, z);
Location currentLocation = getBorderOrigin().add(x, 0, z);
if (currentLocation.x() == borderStartLocation.x() || currentLocation.z() == borderStartLocation.z()) {
if (currentLocation.x() == getBorderOrigin().x() || currentLocation.z() == getBorderOrigin().z()) {
currentLocation.getBlock().setType(Material.RED_CONCRETE);
} else if (currentLocation.x() == borderStartLocation.x() + (pixelsPerBlock+1) || currentLocation.z() == borderStartLocation.z() + (pixelsPerBlock+1)) {
} else if (currentLocation.x() == getBorderOrigin().x() + (pixelsPerBlock+1) || currentLocation.z() == getBorderOrigin().z() + (pixelsPerBlock+1)) {
currentLocation.getBlock().setType(Material.RED_CONCRETE);
}
}
}
for (int x = (2*worldGrassBorderWidth+pixelsPerBlock-1)/2; x < (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+4; x++) {
Random random = new Random();
LocationUtil.iterateBlocks(getPlatformOrigin().add(1, 1, 1), getPlatformOriginEnd().add(0, 1, 0), location -> {
if (allowPlacements(location)) return;
if (!location.clone().subtract(0, 1, 0).getBlock().getType().equals(Material.GRASS_BLOCK)) return;
if (!location.getBlock().getType().equals(Material.AIR)) return;
if (random.nextInt(10) == 0) {
Material[] flowers = {
Material.DANDELION,
Material.POPPY,
Material.BLUE_ORCHID,
Material.ALLIUM,
Material.AZURE_BLUET,
Material.RED_TULIP,
Material.ORANGE_TULIP,
Material.WHITE_TULIP,
Material.CORNFLOWER,
Material.LILY_OF_THE_VALLEY,
};
Material randomFlower = flowers[random.nextInt(flowers.length)];
location.getBlock().setType(randomFlower);
}
});
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 5; y++) {
grassStartLocation.clone().add(x, 1+y, 0).getBlock().setType(Material.OBSIDIAN);
getPortalLocation().add(x, y, 0).getBlock().setType(Material.OBSIDIAN);
}
}
for (int x = (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+1; x < (2*worldGrassBorderWidth+pixelsPerBlock-1)/2+3; x++) {
for (int x = 1; x < 3; x++) {
for (int y = 1; y < 4; y++) {
grassStartLocation.clone().add(x, 1+y, 0).getBlock().setType(Material.NETHER_PORTAL);
getPortalLocation().add(x, y, 0).getBlock().setType(Material.NETHER_PORTAL);
}
}
});

View File

@ -0,0 +1,30 @@
package eu.mhsl.minecraft.pixelblocks.utils;
import org.bukkit.Location;
import org.bukkit.World;
import java.util.function.Consumer;
public class LocationUtil {
public static void iterateBlocks(Location loc1, Location loc2, Consumer<Location> action) {
if (loc1.getWorld() != loc2.getWorld()) {
throw new IllegalArgumentException("Locations must be in the same world");
}
World world = loc1.getWorld();
int minX = Math.min(loc1.getBlockX(), loc2.getBlockX());
int maxX = Math.max(loc1.getBlockX(), loc2.getBlockX());
int minY = Math.min(loc1.getBlockY(), loc2.getBlockY());
int maxY = Math.max(loc1.getBlockY(), loc2.getBlockY());
int minZ = Math.min(loc1.getBlockZ(), loc2.getBlockZ());
int maxZ = Math.max(loc1.getBlockZ(), loc2.getBlockZ());
for (int x = minX; x <= maxX; x++) {
for (int y = minY; y <= maxY; y++) {
for (int z = minZ; z <= maxZ; z++) {
action.accept(new Location(world, x, y, z));
}
}
}
}
}