BukkitAPIにおいて、Playerクラスから使えるメソッドの内、経験値に関係するものがいくつかあります。
totalExp(これまで取得した経験値量の合計)関係
getTotalExperience() : int - Player
: _totalExp_を取得するsetTotalExperience(int arg) : void - Player
: _totalExp_をセットする
exp(現在のXPゲージの割合。0.0~1.0で表す)関係
getExp() : float - Player
: _exp_を取得するsetExp(float arg) : void - Player
: _exp_をセットするgiveExp(int amount) : void - Player
: _exp_を追加する(一定の経験値量貯まればレベルも上がる)
level(レベル)関係
getLevel() : int - Player
: _level_を取得するsetLevel(int arg) : void - Player
: _level_をセットするgiveExpLevels(int amount) : void - Player
: _level_を追加する(5レベル毎の効果音あり)
その他
getExpToLevel() : int - HumanEntity
: 次のレベルまでに必要な最大経験値量を取得する
しかしながら、「現在所持している経験値量を取得」できるメソッドは見当たりません。
また、「経験値量をセットして、レベルとXPゲージに反映される」のもありません。
注意
getTotalExperience()
との違いは、『現在所持している』かどうかです。
getTotalExperience()
はこれまで取得した経験値量なので、
エンチャント等で所持経験値量が減ってもこの値は変わりません。
この問題を解決するため、とりあえず自分で作ってみましょう。
わりと簡単です。
要は、現在のレベルまでに必要だった経験値量の合計と、XPゲージにある経験値量を足せば求まります。
まず、「現在のレベルまでに必要だった経験値量の合計」を求めます。
上記のgetExpToLevel()
がありますが、ソースを解釈すると以下のようになります。
レベル | 次レベルまでに必要な最大経験値量 |
---|---|
0 <= level < 15 | level * 2 + 7 |
15 <= level < 30 | (level - 15) * 5 + 37 |
30 <= level | (level - 30) * 9 + 112 |
これを用いて以下のメソッドを先に用意します。
private static int getExpToLevel(int level) {
return level>=30 ? 112+(level-30)*9 : level>=15 ? 37+(level-15)*5 : 7+level*2;
}
指定したlevelの値から次のレベルまでに必要な最大経験値量を返します。
これを0レベルから現在のレベルまでforでぐるぐるさせれば、
「現在のレベルまでに必要だった経験値量の合計」が求まりますね。
int lv_exp = 0;
for(int l = 0; l < player.getLevel(); l++) {
lv_exp += getExpToLevel(l);
}
次に「XPゲージにある経験値量」を求まります。
ところで、_exp_は「XPゲージの割合」だと上で書きましたが、
詳しく言えば、(XPゲージにある経験値量) / (次のレベルまでに必要な最大経験値量)
となっています。
はい、なので(次のレベルまでに必要な最大経験値量)に「XPゲージの割合」を掛ければ求まりますね。
int exp = Math.round((float)player.getExpToLevel() * player.getExp());
これらを合わせて
public static int getTotalExp(Player player) {
int lv_exp = 0;
for(int l = 0; l < player.getLevel(); l++) {
lv_exp += getExpToLevel(l);
}
int exp = Math.round((float)player.getExpToLevel() * player.getExp());
return lv_exp + exp;
}
private static int getExpToLevel(int level) {
return level>=30 ? 112+(level-30)*9 : level>=15 ? 37+(level-15)*5 : 7+level*2;
}
となりました。
指定した経験値量からレベルとXPゲージをセットしましょう。
構想としては、レベル0から繰り返しで1レベル毎回して必要経験値を合計し、
引数の値より大きくなったら繰り返しを止めればレベルが求められ、
ついでに割合も求めればXPゲージも求めれるでしょう。
(なんかもう上手く説明出来ないから理解して)
完成したのがこちらです。
public static void setTotalExp(Player player, int exp) {
int lv = 0;
int next = getExpToLevel(lv);
int total = next;
while(total <= exp) {
lv++;
next = getExpToLevel(lv);
total += next;
}
total -= next;
player.setLevel(lv);
player.setExp((float)(exp - total)/(float)next);
}
private static int getExpToLevel(int level) {
return level>=30 ? 112+(level-30)*9 : level>=15 ? 37+(level-15)*5 : 7+level*2;
}
以上でやりたいことは終わりです。
Bukkitは非常にべんりですね。
お疲れ様でした。