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
. 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
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!