Solved Particle Issues

Discussion in 'Plugin Development' started by _Bedo_, Jul 23, 2015.

Thread Status:
Not open for further replies.
  1. I'm currently in the process of creating my own set of plugins that could be similar to running a network. While I will never use the in public servers, I'm doing it expand my knowledge of coding for a server. Either way, I've recently started the cosmetics plugin and I am running into some issues with particle trails. This video should demonstrate it:

    The particle trail has two 'states' one for when the player is moving (the random particles around the players body) and one for when they are standing still (the waving circles around them). The problem is it takes a long time to change from the moving to the non-moving particles.
    In order to detect if the player is moving I use the following class, repeating every 5 ticks:
    Code:
    package io.github.Bedo9041.SurvivalCosmetic.Events;
    
    import io.github.Bedo9041.SurvivalCosmetic.SurvivalCosmetic;
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;
    
    import java.util.HashMap;
    import java.util.Map;
    
    public class MovementCheck extends BukkitRunnable {
    
        Map<Player, Location> loc = new HashMap<>();
    
        public void run() {
            for(Player pl : Bukkit.getOnlinePlayers()) {
                if(!loc.containsKey(pl)) {
                    loc.put(pl, pl.getLocation());
                } else {
                    Location currentLoc = pl.getLocation();
                    Location preLoc = loc.get(pl);
                    if (currentLoc.getX() == preLoc.getX() && currentLoc.getY() == preLoc.getY() && currentLoc.getZ() == preLoc.getZ()) {
                        SurvivalCosmetic.getInstance().getMoving().remove(pl);
                    } else {
                        SurvivalCosmetic.getInstance().getMoving().add(pl);
                        loc.replace(pl, pl.getLocation());
                    }
                }
            }
        }
    
        public void clearData(Player player) {
            loc.remove(player);
        }
    }
    
    For the actual particle trails, the following code handles the trail, repeating every 1 tick:
    Code:
    package io.github.Bedo9041.SurvivalCosmetic.Particle.Trail;
    
    import io.github.Bedo9041.SurvivalCore.Main;
    import io.github.Bedo9041.SurvivalCosmetic.Particle.Particles;
    import io.github.Bedo9041.SurvivalCosmetic.Particle.Util.ParticleUtil;
    import io.github.Bedo9041.SurvivalCosmetic.SurvivalCosmetic;
    import net.minecraft.server.v1_8_R3.EnumParticle;
    import org.bukkit.entity.Player;
    import org.bukkit.scheduler.BukkitRunnable;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    public class CritTrail extends BukkitRunnable {
    
        Map<Player, Double> degrees = new HashMap<>();
    
        public void run() {
            for(Player pl : SurvivalCosmetic.getInstance().getActive().keySet()) {
                if(SurvivalCosmetic.getInstance().getActive().get(pl) == Particles.CRIT_TRAIL) {
                    List<Player> ignore = new ArrayList<>();
                    if(!Main.getInstance().getPreferences().get(pl.getUniqueId()).isParticlesSelf())
                        ignore.add(pl);
                    if(SurvivalCosmetic.getInstance().getMoving().contains(pl)) {
                        ParticleUtil.spawnParticle(pl.getLocation().add(0D, 1D, 0D), EnumParticle.CRIT, 0.2f, 0.4f, 0.2f, ignore);
                        degrees.remove(pl);
                    } else {
                        if(degrees.containsKey(pl)) {
                            degrees.replace(pl, degrees.get(pl) + 3D);
                        } else {
                            degrees.put(pl, 0D);
                        }
                        double y = (Math.sin((degrees.get(pl)) * 2D) / 2) + 1D;
                        double x = Math.cos(degrees.get(pl) * Math.PI / 180);
                        double z = Math.sin(degrees.get(pl) * Math.PI / 180);
                        double x2 = Math.cos((degrees.get(pl) + 180D) * Math.PI / 180);
                        double z2 = Math.sin((degrees.get(pl) + 180D) * Math.PI / 180);
                        ParticleUtil.spawnParticle(pl.getLocation().add(x, y, z), EnumParticle.CRIT, 0f, 0f, 0f, ignore);
                        ParticleUtil.spawnParticle(pl.getLocation().add(x2, y, z2), EnumParticle.CRIT, 0f, 0f, 0f, ignore);
                    }
                }
            }
        }
    
        public void clearData(Player player) {
            degrees.remove(player);
        }
    }
    
    And the following code actually dispatches the particle effect:
    Code:
    package io.github.Bedo9041.SurvivalCosmetic.Particle.Util;
    
    import io.github.Bedo9041.SurvivalCosmetic.SurvivalCosmetic;
    import net.minecraft.server.v1_8_R3.EnumParticle;
    import net.minecraft.server.v1_8_R3.PacketPlayOutWorldParticles;
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
    import org.bukkit.entity.Player;
    
    import java.util.List;
    
    public class ParticleUtil {
    
        public static void spawnParticle(Location location, EnumParticle particleID, float offx, float offy, float offz, List<Player> ignorePlayers) {
            if (SurvivalCosmetic.getInstance().isDisableParticles())
                return;
            PacketPlayOutWorldParticles packet = new PacketPlayOutWorldParticles(particleID, true, (float) location.getX(), (float) location.getY(), (float) location.getZ(), offx, offy, offz, 0f, 1, null);
            for (Player player : Bukkit.getOnlinePlayers()) {
                if (!ignorePlayers.contains(player) && !SurvivalCosmetic.getInstance().getGlobalIgnore().contains(player))
                    ((CraftPlayer) player).getHandle().playerConnection.sendPacket(packet);
            }
        }
    }
    
    The movement detector works correctly, he's a video showing the console with a bit of debug code next to the game:

    The main issue with the bug is that it only works one way, when the player starts moving, the particles change instantly. In addition, the longer the player moves, the longer it takes for the particles to change to the 'not moving' state.
    I've tried to fix this a multitude of different ways, such as, changing the delays, changing the particle type etc. and none of the seem to work. Any help would be appreciated, thanks! :)
    EDIT: You can find the full code for the plugin here: https://github.com/Bedo9041/SurvivalCosmetic
     
  2. Still having issues, anyone know a solution?
    EDIT: Resolved
     
    Last edited: Jul 26, 2015
Thread Status:
Not open for further replies.

Share This Page