added lazer gun item

This commit is contained in:
ImproperIssues
2023-07-29 15:28:31 -07:00
parent 2b8ae6af2e
commit 79ed948841
5 changed files with 339 additions and 0 deletions

View File

@@ -182,6 +182,12 @@ public abstract class ItemPresets {
.customModelData(1111)
.build();
public static ItemStack LAZER_GUN = ItemBuilder.create()
.material(Material.IRON_HORSE_ARMOR)
.name(Text.ofAll("&aGreen &7Lazer Blaster"))
.lore(Text.ofAll("&8click to shoot"))
.build();
public static ItemStack BLANK = ItemBuilder.create()
.material(Material.LIGHT_GRAY_STAINED_GLASS_PANE)
.name(" ")

View File

@@ -1,5 +1,6 @@
package fun.ogre.ogredupealias.plugin.custom.items;
import fun.ogre.ogredupealias.plugin.custom.items.customitems.LazerGunItem;
import fun.ogre.ogredupealias.plugin.custom.items.customitems.LazerItem;
import fun.ogre.ogredupealias.plugin.custom.items.customitems.RailgunItem;
import fun.ogre.ogredupealias.plugin.custom.items.customitems.TazerItem;
@@ -21,6 +22,7 @@ public final class CustomItems implements Listener {
register(new TazerItem());
register(new LazerItem());
register(new RailgunItem());
register(new LazerGunItem());
}
public static ItemStack register(ItemStack item, CustomItemInteractionCallback interactionCallback) {

View File

@@ -0,0 +1,88 @@
package fun.ogre.ogredupealias.plugin.custom.items.customitems;
import fun.ogre.ogredupealias.plugin.ItemPresets;
import fun.ogre.ogredupealias.plugin.custom.items.CustomItem;
import fun.ogre.ogredupealias.plugin.custom.items.CustomItemInteractionCallback;
import fun.ogre.ogredupealias.utils.SoundPlayer;
import fun.ogre.ogredupealias.utils.raytracers.BlockDisplayRaytracer;
import fun.ogre.ogredupealias.utils.raytracers.CustomDisplayRaytracer;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.block.Action;
import org.bukkit.util.Vector;
import java.util.List;
public class LazerGunItem extends CustomItem {
public static final Material LAZER_COLOR = Material.LIME_CONCRETE;
public LazerGunItem() {
super("lazergun", ItemPresets.LAZER_GUN);
}
@Override
public CustomItemInteractionCallback getCallback() {
return (player, item, event) -> {
Action action = event.getAction();
if (action == Action.RIGHT_CLICK_AIR || action == Action.RIGHT_CLICK_BLOCK) {
SoundPlayer shootSound = new SoundPlayer(player.getLocation(), Sound.BLOCK_BEACON_DEACTIVATE, 10, 10);
shootSound.playWithin(10);
trace(0, 10, player, player.getEyeLocation().add(0, -0.2, 0), player.getLocation().getDirection(), 64, 10);
}
};
}
public void trace(int attempts, int maxAttempts, LivingEntity shooter, Location start, Vector direction, double distance, double damage) {
CustomDisplayRaytracer.Point result = CustomDisplayRaytracer.trace(start, direction, distance, 0.05, point -> {
List<Entity> nearby = point.getNearbyEntities(shooter, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead());
if (!nearby.isEmpty() && nearby.get(0) instanceof LivingEntity entity) {
entity.damage(damage, shooter);
}
return (!nearby.isEmpty() || CustomDisplayRaytracer.HIT_BLOCK.test(point)) && point.getTraveledDist() > 0.3;
});
BlockDisplayRaytracer.trace(LAZER_COLOR, start, result.getLoc(), 10);
SoundPlayer shootSound = new SoundPlayer(result.getLoc(), Sound.BLOCK_BEACON_ACTIVATE, 1, 10);
shootSound.playWithin(10);
if (CustomDisplayRaytracer.HIT_BLOCK.test(result)) {
BlockDisplayRaytracer.outline(LAZER_COLOR, result.getLoc(), 10);
if (attempts < maxAttempts) {
trace(attempts + 1, maxAttempts, shooter, result.getLoc(), reflect(result.getLoc(), direction), distance, damage);
}
}
}
public Vector reflect(Location pointOfContact, Vector incoming) {
Vector negate = incoming.clone().multiply(-1).normalize();
Vector contact = getContactingVector(pointOfContact.getBlock(), pointOfContact).multiply(-1);
Vector reflect = contact.subtract(negate).normalize();
return reflect;
}
public Vector getContactingVector(Block block, Location pointOfContact) {
Vector center = block.getLocation().add(0.5, 0.5, 0.5).toVector();
Vector incoming = center.subtract(pointOfContact.toVector()).normalize();
double x = incoming.dot(new Vector(1, 0, 0));
double y = incoming.dot(new Vector(0, 1, 0));
double z = incoming.dot(new Vector(0, 0, 1));
double ax = Math.abs(x);
double ay = Math.abs(y);
double az = Math.abs(z);
if (ax > ay && ax > az) {
return new Vector(x, 0, 0).normalize();
}
else if (ay > ax && ay > az) {
return new Vector(0, y, 0).normalize();
}
else {
return new Vector(0, 0, z).normalize();
}
}
}

View File

@@ -0,0 +1,103 @@
package fun.ogre.ogredupealias.utils.raytracers;
import fun.ogre.ogredupealias.OgreDupeAlias;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.BlockDisplay;
import org.bukkit.entity.Display;
import org.bukkit.util.Consumer;
import org.bukkit.util.Transformation;
import org.bukkit.util.Vector;
import org.joml.AxisAngle4f;
import org.joml.Vector3f;
public class BlockDisplayRaytracer {
private static final OgreDupeAlias system = OgreDupeAlias.instance;
public static void outline(Material display, Location location, long stayTime) {
outline(display, location, 0.05, stayTime);
}
public static void outline(Material display, Location location, double thickness, long stayTime) {
Location og = location.getBlock().getLocation();
Location a1 = og.clone().add(0, 0, 0);
Location a2 = og.clone().add(1, 0, 0);
Location a3 = og.clone().add(1, 0, 1);
Location a4 = og.clone().add(0, 0, 1);
Location b1 = og.clone().add(0, 1, 0);
Location b2 = og.clone().add(1, 1, 0);
Location b3 = og.clone().add(1, 1, 1);
Location b4 = og.clone().add(0, 1, 1);
trace(display, a1, a2, thickness, stayTime);
trace(display, a2, a3, thickness, stayTime);
trace(display, a3, a4, thickness, stayTime);
trace(display, a4, a1, thickness, stayTime);
trace(display, b1, b2, thickness, stayTime);
trace(display, b2, b3, thickness, stayTime);
trace(display, b3, b4, thickness, stayTime);
trace(display, b4, b1, thickness, stayTime);
trace(display, a1, b1, thickness, stayTime);
trace(display, a2, b2, thickness, stayTime);
trace(display, a3, b3, thickness, stayTime);
trace(display, a4, b4, thickness, stayTime);
}
public static void trace(Material display, Location start, Location end, long stayTime) {
trace(display, start, end.toVector().subtract(start.toVector()), 0.05, end.distance(start), stayTime);
}
public static void trace(Material display, Location start, Location end, double thickness, long stayTime) {
trace(display, start, end.toVector().subtract(start.toVector()), thickness, end.distance(start), stayTime);
}
public static void trace(Material display, Location start, Vector direction, double thickness, double distance, long stayTime) {
World world = start.getWorld();
BlockDisplay beam = world.spawn(start, BlockDisplay.class, entity -> {
AxisAngle4f angle = new AxisAngle4f(0, 0, 0, 1);
Vector3f transition = new Vector3f(-(float)(thickness / 2F));
Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance);
Transformation trans = new Transformation(transition, angle, scale, angle);
Location vector = entity.getLocation();
vector.setDirection(direction);
entity.teleport(vector);
entity.setBlock(display.createBlockData());
entity.setBrightness(new Display.Brightness(15, 15));
entity.setInterpolationDelay(0);
entity.setTransformation(trans);
Bukkit.getScheduler().runTaskLater(system, entity::remove, stayTime);
});
}
public static void trace(Material display, Location start, Vector direction, double thickness, double distance, long stayTime, Consumer<BlockDisplay> onEntitySpawn) {
World world = start.getWorld();
BlockDisplay beam = world.spawn(start, BlockDisplay.class, entity -> {
AxisAngle4f angle = new AxisAngle4f(0, 0, 0, 1);
Vector3f transition = new Vector3f(-(float)(thickness / 2F));
Vector3f scale = new Vector3f((float)thickness, (float)thickness, (float)distance);
Transformation trans = new Transformation(transition, angle, scale, angle);
Location vector = entity.getLocation();
vector.setDirection(direction);
entity.teleport(vector);
entity.setBlock(display.createBlockData());
entity.setBrightness(new Display.Brightness(15, 15));
entity.setInterpolationDelay(0);
entity.setTransformation(trans);
Bukkit.getScheduler().runTaskLater(system, entity::remove, stayTime);
Bukkit.getScheduler().runTaskLater(system, () -> onEntitySpawn.accept(entity), 5);
});
}
}

View File

@@ -0,0 +1,140 @@
package fun.ogre.ogredupealias.utils.raytracers;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class CustomDisplayRaytracer {
public static final Predicate<Point> HIT_BLOCK = point -> {
Block b = point.getBlock();
Vector v = point.getLoc().toVector();
return !b.isPassable() && b.getCollisionShape().getBoundingBoxes().stream().noneMatch(box -> box.contains(v));
};
public static final Predicate<Point> HIT_ENTITY = point -> {
return !point.getNearbyEntities(null, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty();
};
public static final Predicate<Point> HIT_BLOCK_OR_ENTITY = point -> {
return HIT_BLOCK.test(point) || HIT_ENTITY.test(point);
};
public static final Predicate<Point> HIT_BLOCK_AND_ENTITY = point -> {
return HIT_BLOCK.test(point) && HIT_ENTITY.test(point);
};
public static Predicate<Point> hitEntityExclude(Entity exclude) {
return point -> !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty();
}
public static Predicate<Point> hitAnythingExclude(Entity exclude) {
return point -> HIT_BLOCK.test(point) || !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty();
}
public static Predicate<Point> hitEverythingExclude(Entity exclude) {
return point -> HIT_BLOCK.test(point) && !point.getNearbyEntities(exclude, 5, true, 0.1, e -> e instanceof LivingEntity le && !le.isDead()).isEmpty();
}
public static Point trace(Location start, Location end, Predicate<Point> hitCondition) {
return trace(start, end, 0.5, hitCondition);
}
public static Point trace(Location start, Location end, double interval, Predicate<Point> hitCondition) {
return trace(start, end.toVector().subtract(end.toVector()), end.distance(start), interval, hitCondition);
}
public static Point trace(Location start, Vector direction, double distance, Predicate<Point> hitCondition) {
return trace(start, direction, distance, 0.5, hitCondition);
}
public static Point trace(Location start, Vector direction, double distance, double interval, Predicate<Point> hitCondition) {
if (interval < 0) throw new IllegalArgumentException("interval cannot be zero!");
if (distance < 0) throw new IllegalArgumentException("distance cannot be zero!");
for (double i = 0.0; i < distance; i += interval) {
Point point = blocksInFrontOf(start, direction, i, false);
if (hitCondition.test(point)) {
return point;
}
}
return blocksInFrontOf(start, direction, distance, true);
}
public static Point blocksInFrontOf(Location loc, Vector dir, double blocks, boolean missed) {
return new Point(loc.clone().add(dir.getX() * blocks, dir.getY() * blocks, dir.getZ() * blocks), blocks, missed);
}
public static class Point {
private final Location loc;
private final World world;
private final Block block;
private final boolean missed;
private final double traveledDist;
private Point(Location loc, double traveledDist, boolean missed) {
this.loc = loc;
this.world = loc.getWorld();
this.block = loc.getBlock();
this.missed = missed;
this.traveledDist = traveledDist;
if (world == null) {
throw new IllegalArgumentException("point world cannot be null!");
}
}
public List<Entity> getNearbyEntities(Entity exclude, int range, boolean requireContact, double expansionX, double expansionY, double expansionZ, Predicate<Entity> filter) {
return new ArrayList<>(world.getNearbyEntities(loc, range, range, range, e -> {
if (requireContact && !e.getBoundingBox().expand(expansionX, expansionY, expansionZ).contains(loc.toVector())) {
return false;
}
return filter.test(e) && e != exclude;
}));
}
public List<Entity> getNearbyEntities(Entity exclude, int range, boolean requireContact, double expansion, Predicate<Entity> filter) {
return getNearbyEntities(exclude, range, requireContact, expansion, expansion, expansion, filter);
}
public List<Entity> getNearbyEntities(Entity exclude, int range, boolean requireContact, Predicate<Entity> filter) {
return getNearbyEntities(exclude, range, requireContact, 0, filter);
}
public List<Entity> getNearbyEntities(Entity exclude, int range, Predicate<Entity> filter) {
return getNearbyEntities(exclude, range, false, filter);
}
public double getTraveledDist() {
return traveledDist;
}
public boolean wasMissed() {
return missed;
}
public Block getBlock() {
return block;
}
public Location getLoc() {
return loc;
}
public World getWorld() {
return world;
}
public double distance(Location other) {
return other.distance(loc);
}
}
}