Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifiers of variables based on level

Tags:

java

math

bukkit

I'm getting mad with this problem. Well, let's begin. I want to add some modifiers to different minecraft events (such as how much damage is dealed in the EntityDamageByEntityEvent) according to a level that is stored in a MySQL database.

This level system would have 99 levels (1 to 100), beeing 50 the default level; for example, in the case of the EntityDamageByEntityEvent I'd like to change the damage so:

a) If the player had a 50 level, the damage wouldn't be modified (just would would be multiplied by 1).

b) If the player had a 1 level, the damage dealed would be multiplied by 1/3.

c) If the player had level 100, the damage would be miltiplied by 3.

So far, so good, but how could I do it in the case of a player with level 17 or 89? What I want to know is how to convert, let's say, a 1 to 100 scale in a 1/3 to 3, beeing 50 = 1... A little bit mind blowing... Thanks in advance, hope you understood me!

like image 604
pitazzo Avatar asked Oct 21 '22 08:10

pitazzo


1 Answers

If you plot the points (1, 1/3), (50, 1), and (100, 3) on a graph, you'll see that they don't form a line. So it's not clear how your damage-modifier function should behave between those points.

You could do it in piecewise-linear fashion, with linear interpolation from 1 to 50 and (separately) from 50 to 100:

final float scalingFactor;
if (level < 50) {
    // Convert (1..50) range into (0..1) range.
    final float interp = (level - 1) / 49.0;

    // Convert (0..1) range into (1/3..3/3) range.
    scalingFactor = ((interp * 2.0) + 1.0) / 3.0;
}
else {
    // Convert (50..100) range into (0..1) range.
    final float interp = (level - 50) / 50.0;

    // Convert (0..1) range into (1..3) range.
    scalingFactor = (interp * 2.0) + 1.0;
}

return damage * scalingFactor;

Or, if you're willing to have the 1/3 damage be at level 0 instead of 1, you could use an exponential function:

// Convert (0..100) range into (-1..+1) range.
final float interp = (level - 50) / 50.0;

// 3^(-1) == 1/3
// 3^0    == 1
// 3^(+1) == 3
final float scalingFactor = Math.pow(3.0, interp);

return damage * scalingFactor;

With the piecewise-linear approach, the difference in damage from one level to the next is the same for levels between 1 and 50, and the same for levels between 50 and 100, but the difference in damage from level 50 to 51 is significantly greater than from level 49 to 50.

The exponential function gives you a smooth curve, where the difference in damage per level increases gradually over the full range.

like image 142
Wyzard Avatar answered Oct 23 '22 02:10

Wyzard