/* * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT). * * Copyright (c) JCThePants (www.jcwhatever.com) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.jcwhatever.nucleus.internal.managed.particles; import com.jcwhatever.nucleus.managed.particles.IAreaParticle; import com.jcwhatever.nucleus.managed.particles.IParticleEffect; import com.jcwhatever.nucleus.managed.particles.IRGBColorParticle; import com.jcwhatever.nucleus.managed.particles.ISizeableParticle; import com.jcwhatever.nucleus.managed.particles.ISpeedParticle; import com.jcwhatever.nucleus.managed.particles.ParticleType; import com.jcwhatever.nucleus.utils.ArrayUtils; import com.jcwhatever.nucleus.utils.PreCon; import com.jcwhatever.nucleus.utils.ThreadSingletons; import com.jcwhatever.nucleus.utils.coords.ICoords3D; import com.jcwhatever.nucleus.utils.coords.ICoords3Di; import com.jcwhatever.nucleus.utils.coords.LocationUtils; import com.jcwhatever.nucleus.utils.nms.INmsParticleEffectHandler; import com.jcwhatever.nucleus.utils.nms.NmsUtils; import org.bukkit.Bukkit; import org.bukkit.Color; import org.bukkit.Location; import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * Abstract implementation of {@link IParticleEffect}. */ abstract class AbstractParticle implements IParticleEffect { private static final ThreadSingletons<Location> LOCATIONS = LocationUtils.createThreadSingleton(); private final ParticleType _type; private double _radius = 20; private double _radiusSquared = 20 * 20; /** * Constructor. * * @param type The particle type. */ AbstractParticle(ParticleType type) { _type = type; } @Override public ParticleType getType() { return _type; } @Override public double getRadius() { return _radius; } @Override public void setRadius(double radius) { _radius = radius; _radiusSquared = radius * radius; } @Override public boolean showTo(Player player, Location location, int count) { PreCon.notNull(player); PreCon.notNull(location); return player.getWorld().equals(location.getWorld()) && showTo(ArrayUtils.asList(player), location.getX(), location.getY(), location.getZ(), count); } @Override public boolean showTo(Player player, ICoords3D coords, int count) { PreCon.notNull(player); PreCon.notNull(coords); return showTo(ArrayUtils.asList(player), coords.getX(), coords.getY(), coords.getZ(), count); } @Override public boolean showTo(Player player, ICoords3Di coords, int count) { PreCon.notNull(player); PreCon.notNull(coords); PreCon.positiveNumber(count); return showTo(ArrayUtils.asList(player), coords.getX(), coords.getY(), coords.getZ(), count); } @Override public boolean showTo(Collection<? extends Player> players, Location location, int count) { PreCon.notNull(players); PreCon.notNull(location); List<Player> list = new ArrayList<>(players.size()); for (Player player : players) { if (!player.getWorld().equals(location.getWorld())) continue; list.add(player); } return showTo(list, location.getX(), location.getY(), location.getZ(), count); } @Override public boolean showTo(Collection<? extends Player> players, ICoords3D coords, int count) { PreCon.notNull(players); PreCon.notNull(coords); return showTo(players, coords.getX(), coords.getY(), coords.getZ(), count); } @Override public boolean showTo(Collection<? extends Player> players, ICoords3Di coords, int count) { PreCon.notNull(players); PreCon.notNull(coords); return showTo(players, coords.getX(), coords.getY(), coords.getZ(), count); } @Override public boolean showFrom(Location location, int count) { PreCon.notNull(location); Collection<? extends Player> players = Bukkit.getOnlinePlayers(); List<Player> visible = new ArrayList<>(30); for (Player player : players) { if (!player.getWorld().equals(location.getWorld())) continue; Location playerLocation = player.getLocation(LOCATIONS.get()); if (playerLocation.distanceSquared(location) > radiusSquared()) continue; visible.add(player); } return !visible.isEmpty() && showTo(visible, location.getX(), location.getY(), location.getZ(), count); } protected float getNmsSpeed() { if (this instanceof ISpeedParticle) return ((ISpeedParticle)this).getSpeed(); if (this instanceof ISizeableParticle) return ((ISizeableParticle)this).getSize(); return 1.0f; } protected double radiusSquared() { return _radiusSquared; } protected double getOffsetX() { if (this instanceof IAreaParticle) return ((IAreaParticle)this).getXArea(); return 0.0f; } protected double getOffsetY() { if (this instanceof IAreaParticle) return ((IAreaParticle)this).getYArea(); return 0.0f; } protected double getOffsetZ() { if (this instanceof IAreaParticle) return ((IAreaParticle)this).getZArea(); return 0.0f; } protected void showParticleTo(INmsParticleEffectHandler handler, Collection<? extends Player> players, double x, double y, double z, int count) { PreCon.greaterThanZero(count, "count"); handler.send(players, getType(), true, x, y, z, getOffsetX(), getOffsetY(), getOffsetZ(), getNmsSpeed(), count - 1); } private boolean showTo(Collection<? extends Player> players, double x, double y, double z, int count) { INmsParticleEffectHandler handler = NmsUtils.getParticleEffectHandler(); if (handler == null) return false; if (this instanceof AbstractRGBColorParticle) { ((AbstractRGBColorParticle)this).showColoredTo(handler, players, x, y, z, count); return true; } else { showParticleTo(handler, players, x, y, z, count); } return true; } static class ColorHelper implements IRGBColorParticle { private Color color; private double red; private double green; private double blue; ColorHelper() { setColor(Color.LIME); } @Override public Color getColor() { return color; } @Override public void setColor(Color color) { PreCon.notNull(color); this.color = color; red = color.getRed() / 255D; green = color.getGreen() / 255D; blue = color.getBlue() / 255D; } @Override public double getRed() { return red; } @Override public double getGreen() { return green; } @Override public double getBlue() { return blue; } } static class AreaHelper implements IAreaParticle { private double x; private double y; private double z; @Override public double getXArea() { return x; } @Override public double getYArea() { return y; } @Override public double getZArea() { return z; } @Override public void setXArea(double areaSize) { PreCon.positiveNumber(areaSize); x = areaSize; } @Override public void setYArea(double areaSize) { PreCon.positiveNumber(areaSize); y = areaSize; } @Override public void setZArea(double areaSize) { PreCon.positiveNumber(areaSize); z = areaSize; } @Override public void setArea(double areaSize) { PreCon.positiveNumber(areaSize); x = areaSize; y = areaSize; z = areaSize; } } }