package be.isach.ultracosmetics.cosmetics.gadgets; import be.isach.ultracosmetics.UltraCosmetics; import be.isach.ultracosmetics.UltraCosmeticsData; import be.isach.ultracosmetics.config.MessageManager; import be.isach.ultracosmetics.cosmetics.type.GadgetType; import be.isach.ultracosmetics.player.UltraPlayer; import be.isach.ultracosmetics.util.BlockUtils; import be.isach.ultracosmetics.util.ItemFactory; import be.isach.ultracosmetics.util.MathUtils; import be.isach.ultracosmetics.util.Particles; import be.isach.ultracosmetics.util.ServerVersion; import be.isach.ultracosmetics.util.UtilParticles; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Random; /** * Represents an instance of a discoball gadget summoned by a player. * * @author iSach * @since 08-03-2015 */ public class GadgetDiscoBall extends Gadget { public static final List<GadgetDiscoBall> DISCO_BALLS = new ArrayList<>(); private Random r = new Random(); private int i = 0; private double i2 = 0; private ArmorStand armorStand; private boolean running = false; public GadgetDiscoBall(UltraPlayer owner, UltraCosmetics ultraCosmetics) { super(owner, GadgetType.DISCOBALL, ultraCosmetics); } @Override void onRightClick() { armorStand = (ArmorStand) getPlayer().getWorld().spawnEntity(getPlayer().getLocation().add(0, 3, 0), EntityType.ARMOR_STAND); armorStand.setMetadata("NO_INTER", new FixedMetadataValue(getUltraCosmetics(), "")); armorStand.setVisible(false); armorStand.setGravity(false); armorStand.setSmall(false); armorStand.setHelmet(ItemFactory.create(Material.STAINED_GLASS, (byte) 3, " ")); running = true; DISCO_BALLS.add(this); Bukkit.getScheduler().runTaskLater(getUltraCosmetics(), this::clean, 400); } @Override protected boolean checkRequirements(PlayerInteractEvent event) { if (GadgetDiscoBall.DISCO_BALLS.size() > 0) { getPlayer().sendMessage(MessageManager.getMessage("Gadgets.DiscoBall.Already-Active")); return false; } if (getPlayer().getLocation().add(0, 4, 0).getBlock() != null && getPlayer().getLocation().add(0, 4, 0).getBlock().getType() != Material.AIR) { getPlayer().sendMessage(MessageManager.getMessage("Gadgets.DiscoBall.Not-Space-Above")); return false; } return true; } @Override public void onUpdate() { if (armorStand != null && armorStand.isValid() && running) { armorStand.setHeadPose(armorStand.getHeadPose().add(0, 0.2, 0)); if (UltraCosmeticsData.get().getServerVersion().compareTo(ServerVersion.v1_9_R1) < 0) { armorStand.setHelmet(ItemFactory.create(Material.STAINED_GLASS, (byte) r.nextInt(15), " ")); } UtilParticles.display(Particles.SPELL, armorStand.getEyeLocation(), 1, 1f); UtilParticles.display(Particles.SPELL_INSTANT, armorStand.getEyeLocation(), 1, 1f); Location loc = armorStand.getEyeLocation().add(MathUtils.randomDouble(-4, 4), MathUtils.randomDouble(-3, 3), MathUtils.randomDouble(-4, 4)); Particles.NOTE.display(new Particles.NoteColor(r.nextInt(25)), loc, 128); double angle, angle2, x, x2, z, z2; angle = 2 * Math.PI * i / 100; x = Math.cos(angle) * 4; z = Math.sin(angle) * 4; if (UltraCosmeticsData.get().isUsingSpigot()) { drawParticleLine(armorStand.getEyeLocation().add(-.5d, -.5d, -.5d).clone().add(0.5, 0.5, 0.5).clone().add(x, 0, z), armorStand.getEyeLocation().add(-.5d, -.5d, -.5d).clone().add(0.5, 0.5, 0.5), false, 20); } i += 6; angle2 = 2 * Math.PI * i2 / 100; x2 = Math.cos(angle2) * 4; z2 = Math.sin(angle2) * 4; drawParticleLine(armorStand.getEyeLocation().add(-.5d, -.5d, -.5d).clone().add(0.5, 0.5, 0.5), armorStand.getEyeLocation().add(-.5d, -.5d, -.5d).clone().add(0.5, 0.5, 0.5).add(x2, 0, z2), true, 50); i2 += 0.4; for (Entity ent : getNearbyEntities(armorStand.getEyeLocation().add(-.5d, -.5d, -.5d), 7.5)) { if (ent.isOnGround() && affectPlayers) { MathUtils.applyVelocity(ent, new Vector(0, 0.3, 0)); } } for (Block b : BlockUtils.getBlocksInRadius(armorStand.getEyeLocation().add(-.5d, -.5d, -.5d), 10, false)) { if (b.getType() == Material.WOOL || b.getType() == Material.CARPET) { BlockUtils.setToRestore(b, b.getType(), (byte) r.nextInt(15), 4); } } } else { i = 0; i2 = 0; clean(); } } private void clean() { running = false; if(armorStand != null) { armorStand.remove(); armorStand = null; } DISCO_BALLS.remove(this); } @Override public void onClear() { clean(); } public ArrayList<Entity> getNearbyEntities(Location loc, double distance) { ArrayList<Entity> entities = new ArrayList<>(); Iterator<Entity> iterator = loc.getWorld().getEntities().iterator(); while(iterator.hasNext()) { Entity ent = iterator.next(); if (ent.getLocation().distance(loc) <= distance) { entities.add(ent); } } return entities; } public void drawParticleLine(Location a, Location b, boolean dust, int particles) { Location location = a.clone(); Location target = b.clone(); double amount = particles; Vector link = target.toVector().subtract(location.toVector()); float length = (float) link.length(); link.normalize(); float ratio = length / particles; Vector v = link.multiply(ratio); if (!dust) MathUtils.rotateAroundAxisX(v, i); else { MathUtils.rotateAroundAxisZ(v, i2 / 5); MathUtils.rotateAroundAxisX(v, i2 / 5); } Location loc = location.clone().subtract(v); int step = 0; for (int i = 0; i < particles; i++) { if (step >= amount) step = 0; step++; loc.add(v); if (dust) { UtilParticles.display(MathUtils.random(255), MathUtils.random(255), MathUtils.random(255), loc); continue; } // location.getWorld().spigot().playEffect(loc, Effect.POTION_SWIRL); } } @Override void onLeftClick() { } }