From ba11d74a4a763af726fba340f94a1cd83960dbce Mon Sep 17 00:00:00 2001 From: ImproperIssues Date: Fri, 2 Jun 2023 22:48:26 -0700 Subject: [PATCH] raycast utils --- .../data/builder/BlockPosMatcher.java | 7 +- .../events/InteractionListener.java | 65 ++++++++++++++++++- .../ogredupealias/plugin/ItemPresets.java | 8 +++ .../plugin/custom/forging/CraftingKeys.java | 1 + .../ogre/ogredupealias/utils/ItemUtils.java | 4 ++ .../ogredupealias/utils/RaycastUtils.java | 52 +++++++++++++++ 6 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 src/main/java/fun/ogre/ogredupealias/utils/RaycastUtils.java diff --git a/src/main/java/fun/ogre/ogredupealias/data/builder/BlockPosMatcher.java b/src/main/java/fun/ogre/ogredupealias/data/builder/BlockPosMatcher.java index 7e0e87f..6a5a83d 100644 --- a/src/main/java/fun/ogre/ogredupealias/data/builder/BlockPosMatcher.java +++ b/src/main/java/fun/ogre/ogredupealias/data/builder/BlockPosMatcher.java @@ -1,6 +1,7 @@ package fun.ogre.ogredupealias.data.builder; import fun.ogre.ogredupealias.data.Direction; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -70,6 +71,10 @@ public class BlockPosMatcher { } public static BlockPosMatcher of(Block block) { - return new BlockPosMatcher(block); + return new BlockPosMatcher(block != null ? block : getZero()); + } + + public static Block getZero() { + return new Location(Bukkit.getWorlds().get(0), 0, 0, 0).getBlock(); } } diff --git a/src/main/java/fun/ogre/ogredupealias/events/InteractionListener.java b/src/main/java/fun/ogre/ogredupealias/events/InteractionListener.java index 5bc8c83..33bb4d6 100644 --- a/src/main/java/fun/ogre/ogredupealias/events/InteractionListener.java +++ b/src/main/java/fun/ogre/ogredupealias/events/InteractionListener.java @@ -2,11 +2,26 @@ package fun.ogre.ogredupealias.events; import fun.ogre.ogredupealias.data.PlacedStructures; import fun.ogre.ogredupealias.plugin.InventoryPresets; +import fun.ogre.ogredupealias.plugin.ItemPresets; +import fun.ogre.ogredupealias.utils.ItemUtils; +import fun.ogre.ogredupealias.utils.RaycastUtils; +import org.bukkit.Location; +import org.bukkit.Particle; +import org.bukkit.World; import org.bukkit.block.Block; +import org.bukkit.entity.Entity; +import org.bukkit.entity.Fireball; +import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import org.bukkit.event.block.Action; import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; + +import java.util.ArrayList; +import java.util.List; public class InteractionListener implements Listener { @@ -14,8 +29,11 @@ public class InteractionListener implements Listener { public void onClick(PlayerInteractEvent e) { try { this.processTable(e); + this.handleNetskyBlade(e); + } + catch (Exception ignore) { + ignore.printStackTrace(); } - catch (Exception ignore) {} } private void processTable(PlayerInteractEvent e) { @@ -27,4 +45,49 @@ public class InteractionListener implements Listener { p.openInventory(InventoryPresets.createCustomTable()); } } + + private void handleNetskyBlade(PlayerInteractEvent e) { + Player p = e.getPlayer(); + ItemStack stack = e.getItem(); + Action a = e.getAction(); + + if (ItemUtils.matchDisplay(stack, ItemPresets.NETSKY_BLADE)) { + switch (a) { + case LEFT_CLICK_BLOCK, LEFT_CLICK_AIR -> { + Location start = p.getEyeLocation(); + Vector rotation = p.getLocation().getDirection().normalize(); + + RaycastUtils.raycast(start, rotation, 20, 0.5, 1, point -> { + if (point == null || point.getWorld() == null) return false; + + World w = point.getWorld(); + w.spawnParticle(Particle.FLAME, point, 1, 0, 0, 0, 0); + + List targets = new ArrayList<>(w.getNearbyEntities(point, 2, 2, 2, entity -> { + return entity instanceof LivingEntity living && !living.isDead() && living != p; + })); + + targets.forEach(target -> { + if (target instanceof LivingEntity living) { + living.damage(2.0, p); + living.setFireTicks(60); + } + }); + + return !targets.isEmpty(); + }); + } + case RIGHT_CLICK_AIR, RIGHT_CLICK_BLOCK -> { + Location start = p.getEyeLocation(); + Vector rotation = p.getLocation().getDirection().normalize(); + + p.getWorld().spawn(start, Fireball.class, fireball -> { + fireball.setDirection(rotation); + fireball.setVelocity(rotation.multiply(3)); + fireball.setShooter(p); + }); + } + } + } + } } diff --git a/src/main/java/fun/ogre/ogredupealias/plugin/ItemPresets.java b/src/main/java/fun/ogre/ogredupealias/plugin/ItemPresets.java index 4461f8a..33edef3 100644 --- a/src/main/java/fun/ogre/ogredupealias/plugin/ItemPresets.java +++ b/src/main/java/fun/ogre/ogredupealias/plugin/ItemPresets.java @@ -51,4 +51,12 @@ public abstract class ItemPresets { .enchant(Enchantment.LURE,1) .flag(ItemFlag.HIDE_ENCHANTS) .build(); + + public static ItemStack NETSKY_BLADE = ItemBuilder.create() + .material(Material.NETHERITE_SWORD) + .name(Text.color("&7//&d&l&oNET&5&l&oSKY&7//")) + .lore(Text.color("&7- &dLeft: &5Fire Spell")) + .lore(Text.color("&7- &dRight: &5Fireball")) + .enchant(Enchantment.FIRE_ASPECT, 1) + .build(); } diff --git a/src/main/java/fun/ogre/ogredupealias/plugin/custom/forging/CraftingKeys.java b/src/main/java/fun/ogre/ogredupealias/plugin/custom/forging/CraftingKeys.java index 418729f..00af13d 100644 --- a/src/main/java/fun/ogre/ogredupealias/plugin/custom/forging/CraftingKeys.java +++ b/src/main/java/fun/ogre/ogredupealias/plugin/custom/forging/CraftingKeys.java @@ -13,6 +13,7 @@ public abstract class CraftingKeys { public static void initRecipes() { // my custom + register(ItemPresets.NETSKY_BLADE, "[end_crystal{}, ender_pearl{}]"); //register(ItemPresets.TROLL_SWORD,"[dirt{}]"); register(ItemPresets.SNAD,"[sand{}]"); register(ItemPresets.SNAD_COOKIE,"[air{}, sugar{}, air{}, sand{display:{Name:'{\"extra\":[{\"bold\":false,\"italic\":false,\"underlined\":false,\"strikethrough\":false,\"obfuscated\":false,\"color\":\"white\",\"text\":\"Snad\"}],\"text\":\"\"}'}}, cocoa_beans{}, sand{display:{Name:'{\"extra\":[{\"bold\":false,\"italic\":false,\"underlined\":false,\"strikethrough\":false,\"obfuscated\":false,\"color\":\"white\",\"text\":\"Snad\"}],\"text\":\"\"}'}}, air{}, sugar{}, air{}]"); diff --git a/src/main/java/fun/ogre/ogredupealias/utils/ItemUtils.java b/src/main/java/fun/ogre/ogredupealias/utils/ItemUtils.java index 4b118a7..dd29339 100644 --- a/src/main/java/fun/ogre/ogredupealias/utils/ItemUtils.java +++ b/src/main/java/fun/ogre/ogredupealias/utils/ItemUtils.java @@ -50,4 +50,8 @@ public final class ItemUtils { if (meta == null) return def; return meta.hasDisplayName() ? meta.getDisplayName() : def; } + + public static boolean matchDisplay(ItemStack item, ItemStack item2) { + return getDisplay(item).equals(getDisplay(item2)); + } } diff --git a/src/main/java/fun/ogre/ogredupealias/utils/RaycastUtils.java b/src/main/java/fun/ogre/ogredupealias/utils/RaycastUtils.java new file mode 100644 index 0000000..fa12f71 --- /dev/null +++ b/src/main/java/fun/ogre/ogredupealias/utils/RaycastUtils.java @@ -0,0 +1,52 @@ +package fun.ogre.ogredupealias.utils; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.util.Vector; + +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Predicate; + +import static fun.ogre.ogredupealias.OgreDupeAlias.instance; + +public class RaycastUtils { + + public static Location raycast(Location start, Location end, Predicate hitCondition) { + return raycast(start, end, 0.5, hitCondition); + } + + public static Location raycast(Location start, Location end, double frequency, Predicate hitCondition) { + return raycast(start, end.toVector().subtract(start.toVector()).normalize(), start.distance(end), frequency, hitCondition); + } + + public static Location raycast(Location start, Vector rotation, double distance, Predicate hitCondition) { + return raycast(start, rotation, distance, 0.5, hitCondition); + } + + public static Location raycast(Location start, Vector rotation, double distance, double frequency, Predicate hitCondition) { + for (double i = 0.0; i <= distance; i += frequency) { + Location point = start.clone().add(rotation.clone().multiply(i)); + if (hitCondition.test(point)) { + return point; + } + } + return start.clone().add(rotation.clone().multiply(distance)); + } + + public static Location raycast(Location start, Vector rotation, double distance, double frequency, long tickInterval, Predicate hitCondition) { + AtomicReference result = new AtomicReference<>(); + final double[] i = { 0.0 }; + Bukkit.getScheduler().scheduleSyncRepeatingTask(instance, () -> { + if ((i[0] += frequency) <= distance && result.get() == null) { + Location point = start.clone().add(rotation.clone().multiply(i[0])); + if (hitCondition.test(point)) { + result.set(point); + } + } + else if (result.get() != null) { + result.set(start.clone().add(rotation.clone().multiply(distance))); + } + }, 0, tickInterval); + return result.get() != null ? result.get() : start.clone().add(rotation.clone().multiply(distance)); + } +}