package be.isach.ultracosmetics.cosmetics.gadgets; import be.isach.ultracosmetics.UltraCosmetics; import be.isach.ultracosmetics.config.MessageManager; import be.isach.ultracosmetics.player.UltraPlayer; import be.isach.ultracosmetics.cosmetics.type.GadgetType; import be.isach.ultracosmetics.util.*; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.util.Vector; import java.util.HashSet; import java.util.List; import java.util.Set; /** * Represents an instance of a portal gun gadget summoned by a player. * * @author iSach * @since 08-07-2015 */ public class GadgetPortalGun extends Gadget { boolean teleported = false; Location locBlue; BlockFace blueBlockFace; Location locRed; BlockFace redBlockFace; public GadgetPortalGun(UltraPlayer owner, UltraCosmetics ultraCosmetics) { super(owner, GadgetType.PORTALGUN, ultraCosmetics); displayCooldownMessage = false; useTwoInteractMethods = true; } @Override void onRightClick() { SoundUtil.playSound(getPlayer(), Sounds.ENDERMAN_TELEPORT, 0.2f, 1.5f); UtilParticles.drawParticleLine(getPlayer().getEyeLocation().add(getPlayer().getEyeLocation().getDirection().multiply(0.6)), getPlayer().getTargetBlock((HashSet<Material>) null, 20).getLocation(), Particles.REDSTONE, 100, 0, 0, 255); locBlue = getPlayer().getTargetBlock((Set<Material>) null, 20).getLocation(); List<Block> b = getPlayer().getLastTwoTargetBlocks((Set<Material>) null, 20); blueBlockFace = getBlockFace(b.get(0), b.get(1)); locBlue = locBlue.getBlock().getRelative(blueBlockFace).getLocation().add(0, -0.5, -1); if (blueBlockFace == BlockFace.UP || blueBlockFace == BlockFace.DOWN) { locBlue.add(0.5, 0.7, 0.5); } else if (blueBlockFace == BlockFace.WEST) { locBlue.add(0.6, 0.8, 0.5); } else if (blueBlockFace == BlockFace.EAST) { locBlue.add(.3, 0.8, 0.5); } else if (blueBlockFace == BlockFace.NORTH) { locBlue.add(0.4, 1.8, 1.75); } else if (blueBlockFace == BlockFace.SOUTH) { locBlue.add(0.4, 1.8, 1.2); } } @Override void onLeftClick() { SoundUtil.playSound(getPlayer(), Sounds.ENDERMAN_TELEPORT, 0.2f, 1.5f); UtilParticles.drawParticleLine(getPlayer().getEyeLocation().add(getPlayer().getEyeLocation().getDirection().multiply(0.6)), getPlayer().getTargetBlock((HashSet<Material>) null, 20).getLocation(), Particles.REDSTONE, 100, 255, 0, 0); locRed = getPlayer().getTargetBlock((Set<Material>) null, 20).getLocation(); List<Block> b = getPlayer().getLastTwoTargetBlocks((Set<Material>) null, 20); redBlockFace = getBlockFace(b.get(0), b.get(1)); locRed = locRed.clone().getBlock().getRelative(redBlockFace).getLocation().add(0, -0.5, -1); if (redBlockFace == BlockFace.UP || redBlockFace == BlockFace.DOWN) { locRed.add(0.5, 0.7, 0.5); } else if (redBlockFace == BlockFace.WEST) { locRed.add(0.6, 0.8, 0.5); } else if (redBlockFace == BlockFace.EAST) { locRed.add(.3, 0.8, 0.5); } else if (redBlockFace == BlockFace.NORTH) { locRed.add(0.4, 1.8, 1.75); } else if (redBlockFace == BlockFace.SOUTH) { locRed.add(0.4, 1.8, 1.2); } } public Vector getVectorFromBlockFace(BlockFace bf) { Vector v = new Vector(0, 0, 0); if (bf == BlockFace.UP) { v.add(new Vector(0, 0.3, 0)); } else if (bf == BlockFace.DOWN) { v.add(new Vector(0, -0.3, 0)); } else if (bf == BlockFace.WEST) { v.add(new Vector(-0.3, 0, 0)); } else if (bf == BlockFace.EAST) { v.add(new Vector(0.3, 0, 0)); } else if (bf == BlockFace.NORTH) { v.add(new Vector(-0.3, 0, 0)); } else if (bf == BlockFace.SOUTH) { v.add(new Vector(0.3, 0, 0)); } return v; } public float getPitch(BlockFace bf) { float pitch = 0; if (bf == BlockFace.UP) { pitch = -90; } else if (bf == BlockFace.DOWN) { pitch = 90; } return pitch; } public float getYaw(BlockFace bf) { float yaw = 90; if (bf == BlockFace.WEST) { yaw = 90; } else if (bf == BlockFace.EAST) { yaw = -90; } else if (bf == BlockFace.NORTH) { yaw = 180; } else if (bf == BlockFace.SOUTH) { yaw = 0; } return yaw; } public BlockFace getBlockFace(Block a, Block b) { for (BlockFace bf : BlockFace.values()) { if (a.getRelative(bf).getLocation().equals(b.getLocation())) { return bf.getOppositeFace(); } } return null; } @Override public void onUpdate() { if (locBlue != null) { Location portalCenter = locBlue.clone(); if (locRed != null && !teleported) { if(!locRed.getWorld().getName().equals(locBlue.getWorld().getName())) { locRed = null; locBlue = null; getPlayer().sendMessage(MessageManager.getMessage("Gadgets.PortalGun.Different-Worlds")); return; } Location toDistance; if (blueBlockFace == BlockFace.DOWN) { toDistance = getPlayer().getEyeLocation().clone(); } else if (blueBlockFace == BlockFace.UP) { toDistance = getPlayer().getLocation().clone(); } else { toDistance = getPlayer().getLocation().add(0, 1.03, 0); } if (blueBlockFace == BlockFace.UP || blueBlockFace == BlockFace.DOWN) { portalCenter.add(0, 0, 1); } else if (blueBlockFace == BlockFace.NORTH || blueBlockFace == BlockFace.SOUTH) { portalCenter.add(0, -1, 0); } else if (blueBlockFace == BlockFace.EAST || blueBlockFace == BlockFace.WEST) { portalCenter.add(0, 0, 1); } if (toDistance.distance(locBlue) < 1.01) { teleported = true; teleport(getPlayer(), locRed); getPlayer().setVelocity(getVectorFromBlockFace(redBlockFace)); if (redBlockFace == BlockFace.UP || redBlockFace == BlockFace.DOWN) { Location loc = locRed.clone(); loc.setPitch(getPitch(redBlockFace)); teleport(getPlayer(), loc); } else { Location loc = locRed.clone(); loc.setYaw(getYaw(redBlockFace)); teleport(getPlayer(), loc); } Bukkit.getScheduler().runTaskLaterAsynchronously(getUltraCosmetics(), new Runnable() { @Override public void run() { teleported = false; } }, 20); } } Location loc = locBlue.clone(); for (int i = 0; i < 25; i++) { double inc = (2 * Math.PI) / 20; double angle = i * inc; Vector v = new Vector(); v.setX(Math.cos(angle) * 0.3); v.setZ(Math.sin(angle) * 0.3); double x = 0; double z = 0; if (blueBlockFace != BlockFace.UP && blueBlockFace != BlockFace.DOWN) { if (blueBlockFace == BlockFace.EAST || blueBlockFace == BlockFace.WEST) { x = 0; z = 1.5; } else if (blueBlockFace == BlockFace.NORTH || blueBlockFace == BlockFace.SOUTH) { z = 0; x = 1.5; } } MathUtils.rotateVector(v, x, 0, z); UtilParticles.display(31, 0, 127, loc.add(v)); } } if (locRed != null) { if (locBlue != null && !teleported) { if(!locRed.getWorld().getName().equals(locBlue.getWorld().getName())) { locRed = null; locBlue = null; getPlayer().sendMessage(MessageManager.getMessage("Gadgets.PortalGun.Different-Worlds")); return; } Location toDistance; if (redBlockFace == BlockFace.DOWN) { toDistance = getPlayer().getEyeLocation().clone(); } else if (redBlockFace == BlockFace.UP) { toDistance = getPlayer().getLocation().clone(); } else { toDistance = getPlayer().getLocation().add(0, 1.1, 0); } if (toDistance.distance(locRed) < 1.1) { teleported = true; teleport(getPlayer(), locBlue); getPlayer().setVelocity(getVectorFromBlockFace(blueBlockFace)); if (blueBlockFace == BlockFace.UP || blueBlockFace == BlockFace.DOWN) { Location loc = locBlue.clone(); loc.setPitch(getPitch(blueBlockFace)); teleport(getPlayer(), loc); } else { Location loc = locBlue.clone(); loc.setYaw(getYaw(blueBlockFace)); teleport(getPlayer(), loc); } Bukkit.getScheduler().runTaskLaterAsynchronously(getUltraCosmetics(), new Runnable() { @Override public void run() { teleported = false; } }, 20); } } Location loc = locRed.clone(); for (int i = 0; i < 25; i++) { double inc = (2 * Math.PI) / 20; double angle = i * inc; Vector v = new Vector(); v.setX(Math.cos(angle) * 0.3); v.setZ(Math.sin(angle) * 0.3); double x = 0; double z = 0; if (redBlockFace != BlockFace.UP && redBlockFace != BlockFace.DOWN) { if (redBlockFace == BlockFace.EAST || redBlockFace == BlockFace.WEST) { x = 0; z = 1.5; } else if (redBlockFace == BlockFace.NORTH || redBlockFace == BlockFace.SOUTH) { z = 0; x = 1.5; } } MathUtils.rotateVector(v, x, 0, z); UtilParticles.display(255, 0, 0, loc.add(v)); } } } @Override protected boolean checkRequirements(PlayerInteractEvent event) { if (getPlayer().getTargetBlock((Set<Material>) null, 20).getType() == Material.AIR || getPlayer().getLastTwoTargetBlocks((Set<Material>) null, 20).size() < 2) { getPlayer().sendMessage(MessageManager.getMessage("Gadgets.PortalGun.No-Block-Range")); return false; } return true; } public BlockFace[] axis = {BlockFace.NORTH, BlockFace.EAST, BlockFace.SOUTH, BlockFace.WEST}; public BlockFace[] radial = {BlockFace.NORTH, BlockFace.NORTH_EAST, BlockFace.EAST, BlockFace.SOUTH_EAST, BlockFace.SOUTH, BlockFace.SOUTH_WEST, BlockFace.WEST, BlockFace.NORTH_WEST}; public BlockFace yawToFace(float yaw) { return yawToFace(yaw, true); } public BlockFace yawToFace(float yaw, boolean useSubCardinalDirections) { if (useSubCardinalDirections) { return radial[Math.round(yaw / 45f) & 0x7]; } else { return axis[Math.round(yaw / 90f) & 0x3]; } } private void teleport(final Entity entity, final Location location) { Bukkit.getScheduler().runTask(getUltraCosmetics(), new Runnable() { @Override public void run() { entity.teleport(location); if(entity instanceof Player) { SoundUtil.playSound(((Player) entity), Sounds.ENDERMAN_TELEPORT); } } }); } @Override public void onClear() { locBlue = null; locRed = null; } }