diff --git a/modules/Movecraft/src/main/java/net/countercraft/movecraft/listener/BlockListener.java b/modules/Movecraft/src/main/java/net/countercraft/movecraft/listener/BlockListener.java index 394048dcd..6dcdb1f0b 100644 --- a/modules/Movecraft/src/main/java/net/countercraft/movecraft/listener/BlockListener.java +++ b/modules/Movecraft/src/main/java/net/countercraft/movecraft/listener/BlockListener.java @@ -26,6 +26,8 @@ import net.countercraft.movecraft.util.MathUtils; import net.countercraft.movecraft.util.Tags; import net.countercraft.movecraft.util.hitboxes.BitmapHitBox; +import org.apache.commons.math3.util.MathUtils; +import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; @@ -57,12 +59,15 @@ public void onBlockBreak(@NotNull BlockBreakEvent e) { if (e.getBlock().getType() == Material.FIRE) return; // allow players to punch out fire - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(e.getBlock().getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getBlock().getLocation()); - if (craft == null || !craft.getHitBox().contains(loc) || craft.getDisabled()) - return; + Location location = e.getBlock().getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.getDisabled() || !craft.getHitBox().contains(loc)) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } //Prevents non pilots from placing blocks on your ship. @@ -71,150 +76,170 @@ public void onBlockPlace(BlockPlaceEvent e) { if (!Settings.ProtectPilotedCrafts) return; - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(e.getBlockAgainst().getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getBlockAgainst().getLocation()); - if (craft == null || !craft.getHitBox().contains(loc) || craft.getDisabled() || !(craft instanceof PilotedCraft)) - return; - + Location location = e.getBlockAgainst().getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); Player p = e.getPlayer(); - if (((PilotedCraft) craft).getPilot() == p) - return; + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.getDisabled() || !(craft instanceof PilotedCraft) || !craft.getHitBox().contains(loc)) + continue; + if (((PilotedCraft) craft).getPilot() == p) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } // prevent items from dropping from moving crafts - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onItemSpawn(@NotNull ItemSpawnEvent e) { - if (e.isCancelled()) - return; + Location location = e.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.isNotProcessing() || !craft.getHitBox().contains(loc)) + continue; - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(e.getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getLocation()); - if (craft == null || craft.isNotProcessing() || !craft.getHitBox().contains((loc))) + e.setCancelled(true); return; - - e.setCancelled(true); + } } // process certain redstone on cruising crafts - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onRedstoneEvent(@NotNull BlockRedstoneEvent e) { Block block = e.getBlock(); - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(block.getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), block.getLocation()); - if (craft == null || craft.isNotProcessing() || !craft.getHitBox().contains((loc))) - return; - if (block.getType() != Material.STICKY_PISTON || block.getType() != Material.PISTON || block.getType() != Material.DISPENSER) return; - e.setNewCurrent(e.getOldCurrent()); // don't allow piston movement on cruising crafts + Location location = block.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.isNotProcessing() || !craft.getHitBox().contains(loc)) + continue; + + e.setNewCurrent(e.getOldCurrent()); // don't allow piston movement on cruising crafts + return; + } } - // prevent pistons on cruising crafts - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPistonEvent(@NotNull BlockPistonExtendEvent e) { Block block = e.getBlock(); - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(block.getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), block.getLocation()); - if (craft == null || !craft.getHitBox().contains((loc))) - return; - - if (!craft.isNotProcessing()) - e.setCancelled(true); - - if (!craft.getType().getBoolProperty(CraftType.MERGE_PISTON_EXTENSIONS)) - return; - - BitmapHitBox hitBox = new BitmapHitBox(); - for (Block b : e.getBlocks()) { - Vector dir = e.getDirection().getDirection(); - hitBox.add(new MovecraftLocation(b.getX() + dir.getBlockX(), b.getY() + dir.getBlockY(), b.getZ() + dir.getBlockZ())); + Location location = block.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (!craft.getHitBox().contains(loc)) + continue; + + if (!craft.isNotProcessing()) + e.setCancelled(true); // prevent pistons on cruising crafts + + // merge piston extensions to craft + if (craft.getType().getBoolProperty(CraftType.MERGE_PISTON_EXTENSIONS)) + continue; + + BitmapHitBox hitBox = new BitmapHitBox(); + for (Block b : e.getBlocks()) { + Vector dir = e.getDirection().getDirection(); + hitBox.add(new MovecraftLocation(b.getX() + dir.getBlockX(), b.getY() + dir.getBlockY(), b.getZ() + dir.getBlockZ())); + } + craft.setHitBox(craft.getHitBox().union(hitBox)); } - craft.setHitBox(craft.getHitBox().union(hitBox)); } // prevent hoppers on cruising crafts - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onHopperEvent(@NotNull InventoryMoveItemEvent e) { if (!(e.getSource().getHolder() instanceof Hopper)) return; Hopper block = (Hopper) e.getSource().getHolder(); - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(block.getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), block.getLocation()); - if (craft == null || craft.isNotProcessing() || !craft.getHitBox().contains((loc))) - return; + Location location = block.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.isNotProcessing() || !craft.getHitBox().contains(loc)) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } // prevent fragile items from dropping on cruising crafts - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onPhysics(@NotNull BlockPhysicsEvent e) { - if (e.isCancelled()) - return; Block block = e.getBlock(); if (!Tags.FRAGILE_MATERIALS.contains(block.getType())) return; - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(block.getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), block.getLocation()); - if (craft == null || !craft.getHitBox().contains((loc))) - return; + Location location = block.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (!craft.getHitBox().contains(loc)) + continue; + + BlockData m = block.getBlockData(); + BlockFace face = BlockFace.DOWN; + boolean faceAlwaysDown = block.getType() == Material.COMPARATOR || block.getType() == Material.REPEATER; + if (m instanceof Attachable && !faceAlwaysDown) + face = ((Attachable) m).getAttachedFace(); - BlockData m = block.getBlockData(); - BlockFace face = BlockFace.DOWN; - boolean faceAlwaysDown = block.getType() == Material.COMPARATOR || block.getType() == Material.REPEATER; - if (m instanceof Attachable && !faceAlwaysDown) - face = ((Attachable) m).getAttachedFace(); + if (e.getBlock().getRelative(face).getType().isSolid()) + continue; - if (e.getBlock().getRelative(face).getType().isSolid()) + e.setCancelled(true); return; - - e.setCancelled(true); + } } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onBlockDispense(@NotNull BlockDispenseEvent e) { - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(e.getBlock().getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getBlock().getLocation()); - if (craft == null || craft.isNotProcessing() || !craft.getHitBox().contains((loc))) - return; + Location location = e.getBlock().getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (craft.isNotProcessing() || !craft.getHitBox().contains(loc)) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onFlow(@NotNull BlockFromToEvent e) { - if (Settings.DisableSpillProtection || e.isCancelled()) + if (Settings.DisableSpillProtection) return; Block block = e.getBlock(); if (!Tags.FLUID.contains(block.getType())) return; - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(block.getLocation()); + Location location = block.getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); MovecraftLocation toLoc = MathUtils.bukkit2MovecraftLoc(e.getToBlock().getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getBlock().getLocation()); - if (craft == null || !craft.getHitBox().contains((loc)) || craft.getFluidLocations().contains(toLoc)) - return; + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (!craft.getHitBox().contains(loc) || craft.getFluidLocations().contains(toLoc)) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } - @EventHandler + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onIceForm(@NotNull BlockFormEvent e) { - if (e.isCancelled() || !Settings.DisableIceForm) + if (!Settings.DisableIceForm) return; if (Tags.WATER.contains(e.getBlock().getType())) return; - MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(e.getBlock().getLocation()); - Craft craft = MathUtils.fastNearestCraftToLoc(CraftManager.getInstance().getCrafts(), e.getBlock().getLocation()); - if (craft == null || !craft.getHitBox().contains((loc))) - return; + Location location = e.getBlock().getLocation(); + MovecraftLocation loc = MathUtils.bukkit2MovecraftLoc(location); + for (Craft craft : MathUtils.craftsNearLocFast(CraftManager.getInstance().getCrafts(), location)) { + if (!craft.getHitBox().contains(loc)) + continue; - e.setCancelled(true); + e.setCancelled(true); + return; + } } } diff --git a/modules/api/src/main/java/net/countercraft/movecraft/util/MathUtils.java b/modules/api/src/main/java/net/countercraft/movecraft/util/MathUtils.java index 9599334c0..dcb71b916 100644 --- a/modules/api/src/main/java/net/countercraft/movecraft/util/MathUtils.java +++ b/modules/api/src/main/java/net/countercraft/movecraft/util/MathUtils.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.HashSet; import java.util.OptionalInt; import java.util.Set; @@ -230,4 +231,17 @@ public static Craft fastNearestCraftToLoc(@NotNull Set crafts, @NotNull L } return result; } + + @Nullable + public static Set craftsNearLocFast(@NotNull Set crafts, @NotNull Location loc) { + Set result = new HashSet<>(crafts.size(), 1); + MovecraftLocation location = new MovecraftLocation(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ()); + for (Craft i : crafts) { + if (i.getHitBox().isEmpty() || i.getWorld() != loc.getWorld() || !locIsNearCraftFast(i, location)) + continue; + + result.add(i); + } + return result; + } }