Skip to content

Instantly share code, notes, and snippets.

@keepoff07
Last active August 29, 2015 14:23
Show Gist options
  • Save keepoff07/44e9fa5d1edfa0d67f9e to your computer and use it in GitHub Desktop.
Save keepoff07/44e9fa5d1edfa0d67f9e to your computer and use it in GitHub Desktop.
printf("「えーと、次のレベルまで…ネスは"+getTotalExp(ネス)+"。それはそうと何の用だい?」");

Exp now

問題提起

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は非常にべんりですね
お疲れ様でした。

「そうか。
 パパももう今日は休もうと
 思ってたところだ。
 冒険の記録はつけといたよ。
 おやすみ…」
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;
}
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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment