Solved Another loop problem

Discussion in 'Spigot Plugin Development' started by MaveCrit, May 27, 2016.

  1. So i have a little problem with my plugin right now..
    I will explain it to you:
    In my code i loop trough different locations (ArrayList) and check if the config.yml contains that location.
    If so the plugin will return the String name of the location like:
    Code (Text):
    portal_1: world,X,Y,Z,Yaw,Pitch
    So if the ArrayList and the config contains the same X,Y,Z,Yaw,Pitch it will return "portal_1"

    I have done that like that (I'm sure its possible to make it much more easier):

    Saving the location to the config:
    Code (Text):
                            Location location = p.getLocation();
                           
                            Main.locations.set("portal_" + i, location.getWorld().getName() + "," + location.getBlockX()
                            + "," + location.getBlockY() + "," + location.getBlockZ() + ","
                            + location.getYaw() + "," + location.getPitch() + "," + "bungee");
                            Main.locations.saveConfig();

    Put the location in the array list on startup:
    Code (Text):
        public static List<Location> Portals = new ArrayList<Location>();
       
        public static void LoadAll() {
           
           
            for (int i = 1; Main.locations.contains("portal_" + i); i++) {
                Portals.add(GetLocation("portal_" + i));
                 Bukkit.getConsoleSender().sendMessage("┬žaPortal " + i + " has been found!");
               }

        }
        public static Location GetLocation(String Key) {
            if (!Main.locations.contains(Key)) {
                return null;
            }
            String[] v = Main.locations.getString(Key).split(",");

            return new Location(Bukkit.getWorld(v[0]), Double.parseDouble(v[1]),
                    Double.parseDouble(v[2]), Double.parseDouble(v[3]),
                    Float.parseFloat(v[4]), Float.parseFloat(v[5]));
        }

    So lets get to the problem part.
    On startup i also create a particle circle with the radius of 3 on every location
    [​IMG]

    I want to select this "portal" to edit things like "Warp location" or something like that.
    To select i do the thing from above (Check if config contains ArrayList location and return the String-name)

    Thats my way:
    Code (Text):
        public String getNearPortal(Player p){
            String none = "┬žcThere is no near portal";
             for (int i = 0; i < LocationGetter.Portals.size(); i++) {
                  Location loc = (Location)LocationGetter.Portals.get(i);
                  String sloc = "" + loc.getWorld().getName() + "," + loc.getX() + "," + loc.getY() + "," + loc.getZ() + "," + loc.getPitch() + "," + loc.getYaw();
                   if (loc.distance(p.getLocation()) < 10.0D)
                  {
                      for (int id = 1; id < LocationGetter.Portals.size(); id++) {
                           String[] v = Main.locations.getString("portal_" + id).split(",");
                           String[] s = sloc.split(",");
                           
                           String eins = v[1] + ".0";
                           String zwei = v[2] + ".0";
                           String drei = v[3] + ".0";
                           
                           if(v[0].equals(s[0]) && eins.equals(s[1]) && zwei.equals(s[2]) && drei.equals(s[3])){
                               return "portal_" + id;
                           }
                     //return sloc;
                      }      
                  }
             }
            return none;
        }

    So this works fine.. thats what i thought but there is a creepy error which appears.
    It only works for the lowest numbers not for the highest.
    So if i have: portal_1, portal_2, portal_3, portal_4
    It will work for 1,2 and 3. But not for 4.

    Same with: portal_1, portal_2, portal_3, portal_4, portal_5
    It will work for 1,2,3 and 4. But not for 5.


    My config looks like that:

    upload_2016-5-27_12-45-7.png


    Can anyone help me?
     
  2. Can we see the error? The error is the thing that tells us why your code isn't working.
     
  3. Thats the thing, there is no real "error".
    Its just says "There is no real portal" (So its return null)

    But only on the highest number (portal_1, portal_2 ...)
     
  4. So here is a visual demo:
    [​IMG]
    [​IMG]

    [​IMG]


    As you see i stand EXACTLY in front of the portal but it only works for the lower numbers, not for the highest >.<
    I'm very confused.

    Console (No error, not even a Nullpointer)
    upload_2016-5-27_13-15-23.png
     
  5. sothatsit

    Patron

    Can you show your code please where you spawn the particles for the portal.

    Also, please use proper naming conventions for methods and fields, they should be named using lowerCamelCase, starting with a capital letter breaks this convention and makes it seem like they should be classes or enums. It is for code readability.
     
  6. Currently i spawn the portals with EffectLib (I really need a new solution for that because i want to make them per-player)

    Code (Text):
            for (Location block : LocationGetter.Portals)
            {
              CylinderEffect circleEffect = new CylinderEffect(manag);
              circleEffect.setLocation(block);
              circleEffect.enableRotation = false;
              circleEffect.infinite();
              circleEffect.rotationX = 0.0D;
              circleEffect.rotationY = 0.0D;
              circleEffect.rotationZ = 0.0D;
              circleEffect.height = 2.0F;
              circleEffect.visibleRange = 70.0F;
              circleEffect.radius = 3.0F;
              circleEffect.particle = ParticleEffect.FIREWORKS_SPARK;
              circleEffect.particles = 150;
              circleEffect.start();
            }
    And also the EffectLib class:
    Code (Text):
    public class CylinderEffect extends Effect {

        /**
         * Particle of the cube
         */
        public ParticleEffect particle = ParticleEffect.FLAME;

        /**
         * Radius of cylinder
         */
        public float radius = 1;

        /**
         * Height of Cylinder
         */
        public float height = 3;

        /**
         * Turns the cube by this angle each iteration around the x-axis
         */
        public double angularVelocityX = Math.PI / 200;

        /**
         * Turns the cube by this angle each iteration around the y-axis
         */
        public double angularVelocityY = Math.PI / 170;

        /**
         * Turns the cube by this angle each iteration around the z-axis
         */
        public double angularVelocityZ = Math.PI / 155;

        /**
         * Rotation of the cylinder
         */
        public double rotationX, rotationY, rotationZ;

        /**
         * Particles in each row
         */
        public int particles = 100;

        /**
         * True if rotation is enable
         */
        public boolean enableRotation = true;

        /**
         * Toggles the cylinder to be solid
         */
        public boolean solid = false;

        /**
         * Current step. Works as counter
         */
        protected int step = 0;

        /**
         * Ratio of sides to entire surface
         */
        protected float sideRatio = 0;

        public CylinderEffect(EffectManager effectManager) {
            super(effectManager);
            type = EffectType.REPEATING;
            period = 2;
            iterations = 200;
        }

        @Override
        public void onRun() {
            Location location = getLocation();
            if (sideRatio == 0) {
                calculateSideRatio();
            }
            Random r = RandomUtils.random;
            double xRotation = rotationX, yRotation = rotationY, zRotation = rotationZ;
            if (enableRotation) {
                xRotation += step * angularVelocityX;
                yRotation += step * angularVelocityY;
                zRotation += step * angularVelocityZ;
            }
            for (int i = 0; i < particles; i++) {
                float multi = (solid) ? r.nextFloat() : 1;
                Vector v = RandomUtils.getRandomCircleVector().multiply(radius);
                if (r.nextFloat() <= sideRatio) {
                    // SIDE PARTICLE
                    v.multiply(multi);
                    v.setY((r.nextFloat() * 2 - 1) * (height / 2));
                } else {
                    // GROUND PARTICLE
                    v.multiply(r.nextFloat());
                    /*if (r.nextFloat() < 0.5) {
                        // TOP
                        //v.setY(multi * (height / 2));
                    } else {
                        // BOTTOM
                        v.setY(-multi * (height / 2));
                    }*/
                }
                if (enableRotation) {
                    VectorUtils.rotateVector(v, xRotation, yRotation, zRotation);
                }
                particle.display(location.add(v), visibleRange);
                location.subtract(v);
            }
            display(particle, location);
            step++;
        }

        protected void calculateSideRatio() {
            float grounds, side;
            grounds = MathUtils.PI * MathUtils.PI * radius * 2;
            side = 2 * MathUtils.PI * radius * height;
            sideRatio = side / (side + grounds);
        }
     
  7. sothatsit

    Patron

    Should this
    "for (int id = 1; id < LocationGetter.Portals.size(); id++) {"
    not be less than or equal to? Not just less than.
     
  8. Gave it a try but seems to break the other portals as well <.<
     
  9. sothatsit

    Patron

    What did you change it to?

    Looking back, this is definitely your problem.
     
  10. I changed it to "==" but it broke everything BUT i found a solution (Pretty simple but it works)
    Code (Text):
     for (int id = 1; id < (LocationGetter.Portals.size() + 1); id++) {
    That worked for me, solved i think.
    Thank you guys!
     
  11. sothatsit

    Patron

    I said less than or equal to, not equals...

    "id <= LocationGetter.Portals.size()"

    would be a better solution.