• Proceed with caution! Unofficial add-on plugins and abilities are not supported by the ProjectKorra staff. We will not provide support for broken add-ons. Download at your own risk.
  • Hello Guest! Did you know that ProjectKorra has an official Discord server? A lot of discussion about the official server, development process, and community discussion happens over there. Feel free to join now by clicking the link below.

    Join the Discord Server
Blizzard

Blizzard 1.1.1

Vahagn

Staff member
Plugin Developer
Verified Member
ArchBear_Vega submitted a new resource:

Blizzard - Get ready for a flurry!

"This is not an official ProjectKorra ability, therefore, no official support will be provided in any threads other than this one. Use at your own risk."



Who doesn't want to be like their favorite waterbending Overwatch Hero, (yes I am aware she is not a waterbender but she uses ice so she counts)

By left clicking you can unleash the Blizzard from nearby sources and watch as your...
Read more about this resource...
 

Finn_Bueno_

Staff member
Plugin Developer
Verified Member
So I saw someone commented it lags a lot, and since this using a little more 'complicated' spawning of particles, I figured I'd try to help you. So there are 2 main problems I see. (In no way bashing your code, just a fellow programmer trying to help you improve).

First thing is this method.
Code:
public Block getBlocksInRadius(Location center) {
    Block block = null;
    
    int radius = 6;
    for (int x = -radius; x < radius; x++) {
      for (int y = -radius; y < radius; y++) {
        for (int z = -radius; z < radius; z++) {
          if ((x * x + y * y + z * z <= radius * radius) &&
            (isWaterbendable(center.clone().add(x, y, z).getBlock().getType())))
          {
            block = center.clone().add(x, y, z).getBlock();
            return block;
          }
        }
      }
    }
    return block;
  }
First off, what is this for? What I got from looking at the code, is that it's used to check if there is any watersource within 6 blocks during the ability, and if not it doesn't run the rest of the code. (should cancel the ability all together I think).

First off, this is a triple for loop, a thing I'm not a HUGE fan off, but okay. Your radius is 6. Each loop runs from -6 up to 6, leaving us with 6 * 2 + 1= 12 (the + 1 is the actual 6 because you put <= radius instead of < radius). Then we do that by the power of 3, leaving us with 12 ^ 3 = 1728. Do that times 20 to get the amount of executions every second. 1728 * 20 = 34560 times a second. The code within the deepest loop is executed 34560 a second (at most). Not only that, but you also create a new object everytime (Location#clone();). Instead, add x, y, z to the location at the start of the loop, and subtract it at the end, it's more efficient! Besides that all, PK has a built-in method for doing something like this I believe. Check the javadocs.

The second this is this.
Code:
      Location center;
      for (int angle = 0; angle <= 360; angle++)
      {
        center = this.endingLocation.clone();
        double x = Math.cos(angle);
        double z = Math.sin(angle);
        center.setX(center.getX() + x);
        center.setZ(center.getZ() + z);
        this.player.spawnParticle(Particle.SNOW_SHOVEL, center, 1, 0.0D, 0.0D, 0.0D, 1.0E-4D);
      }
There a few things wrong here, and they trigger me quite a bit. No worries, I won't get mad or anything :p. Anyway, here we go.

First off, the Math.sin(double) and Math.cos(double) methods don't work with degrees, but with radians. You are running the code 360 times (for each whole degree), but that's far too much. You'll barely see it. You can safely run it 90 times, which spawns 4 times less particles while still looking like a circle.

Second, you should use radians. You can do this in 2 ways.
1) Convert your degree value to radians using Math.toRadians(double);, which will take a degree value and return the radians value. Simply create a new local double variable with it and pass 'angle' to it, then pass the return value of the method to sin and cos.
2) Change your for loop to use radians instead of degrees. For a further explanation about what radians are (short), read this. So instead of going from 0 to 360, you'd go from 0 to 2 * PI
Code:
for (double angle = 0; angle < 2 * Math.PI;) { /* code */ }
Now for the last part of the loop, you'll add a fraction of 2 * PI to the angle variable. Using this method, you can easily change how many particles you want the loop to spawn. If you want 20 particles in total, all you have to do is divide 2 * PI by 29, and add it to angle:
Code:
angle += Math.PI * 2 / 20) { /* code */ }
Of course, with some simple math we can shorten that down. PI * 2 / 20 is the same as

Which we can shorten by dividing both sides (above and below the line) by 2, giving us

So instead of PI * 2 / 20, you can use PI / 10, which is shorter.

Hope that helps you a bit :p There are a few more flaws but you'll learn about those overtime, or just shoot a PM if you want me to help you out with those too! :)
 

Vahagn

Staff member
Plugin Developer
Verified Member
So I saw someone commented it lags a lot, and since this using a little more 'complicated' spawning of particles, I figured I'd try to help you. So there are 2 main problems I see. (In no way bashing your code, just a fellow programmer trying to help you improve).

First thing is this method.
Code:
public Block getBlocksInRadius(Location center) {
    Block block = null;
   
    int radius = 6;
    for (int x = -radius; x < radius; x++) {
      for (int y = -radius; y < radius; y++) {
        for (int z = -radius; z < radius; z++) {
          if ((x * x + y * y + z * z <= radius * radius) &&
            (isWaterbendable(center.clone().add(x, y, z).getBlock().getType())))
          {
            block = center.clone().add(x, y, z).getBlock();
            return block;
          }
        }
      }
    }
    return block;
  }
First off, what is this for? What I got from looking at the code, is that it's used to check if there is any watersource within 6 blocks during the ability, and if not it doesn't run the rest of the code. (should cancel the ability all together I think).

First off, this is a triple for loop, a thing I'm not a HUGE fan off, but okay. Your radius is 6. Each loop runs from -6 up to 6, leaving us with 6 * 2 + 1= 12 (the + 1 is the actual 6 because you put <= radius instead of < radius). Then we do that by the power of 3, leaving us with 12 ^ 3 = 1728. Do that times 20 to get the amount of executions every second. 1728 * 20 = 34560 times a second. The code within the deepest loop is executed 34560 a second (at most). Not only that, but you also create a new object everytime (Location#clone();). Instead, add x, y, z to the location at the start of the loop, and subtract it at the end, it's more efficient! Besides that all, PK has a built-in method for doing something like this I believe. Check the javadocs.

The second this is this.
Code:
      Location center;
      for (int angle = 0; angle <= 360; angle++)
      {
        center = this.endingLocation.clone();
        double x = Math.cos(angle);
        double z = Math.sin(angle);
        center.setX(center.getX() + x);
        center.setZ(center.getZ() + z);
        this.player.spawnParticle(Particle.SNOW_SHOVEL, center, 1, 0.0D, 0.0D, 0.0D, 1.0E-4D);
      }
There a few things wrong here, and they trigger me quite a bit. No worries, I won't get mad or anything :p. Anyway, here we go.

First off, the Math.sin(double) and Math.cos(double) methods don't work with degrees, but with radians. You are running the code 360 times (for each whole degree), but that's far too much. You'll barely see it. You can safely run it 90 times, which spawns 4 times less particles while still looking like a circle.

Second, you should use radians. You can do this in 2 ways.
1) Convert your degree value to radians using Math.toRadians(double);, which will take a degree value and return the radians value. Simply create a new local double variable with it and pass 'angle' to it, then pass the return value of the method to sin and cos.
2) Change your for loop to use radians instead of degrees. For a further explanation about what radians are (short), read this. So instead of going from 0 to 360, you'd go from 0 to 2 * PI
Code:
for (double angle = 0; angle < 2 * Math.PI;) { /* code */ }
Now for the last part of the loop, you'll add a fraction of 2 * PI to the angle variable. Using this method, you can easily change how many particles you want the loop to spawn. If you want 20 particles in total, all you have to do is divide 2 * PI by 29, and add it to angle:
Code:
angle += Math.PI * 2 / 20) { /* code */ }
Of course, with some simple math we can shorten that down. PI * 2 / 20 is the same as

Which we can shorten by dividing both sides (above and below the line) by 2, giving us

So instead of PI * 2 / 20, you can use PI / 10, which is shorter.

Hope that helps you a bit :p There are a few more flaws but you'll learn about those overtime, or just shoot a PM if you want me to help you out with those too! :)
Thanks for the advice, Ill be sure to make this more efficient and less buggy with it.
 

Finn_Bueno_

Staff member
Plugin Developer
Verified Member
Thanks for the advice, Ill be sure to make this more efficient and less buggy with it.
That's the spirit! ;) Also I didn't notice you're a concept designer up until now, I like seeing concept designers learning programming. It's always better to have some knowledge of what your 'colleagues' work on.
 
Top