Last active
September 30, 2015 03:13
-
-
Save ucchyocean/03ea7e4af90ce7499bff to your computer and use it in GitHub Desktop.
木こりプラグインを作ってみた
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* きこりプラグイン | |
* @author ucchy | |
*/ | |
public class WoodChopper extends JavaPlugin implements Listener { | |
private static final int MAX_CHECK_NUM = 100; | |
/** | |
* プラグインが有効化されたときに呼び出されるメソッド | |
* @see org.bukkit.plugin.java.JavaPlugin#onEnable() | |
*/ | |
@Override | |
public void onEnable() { | |
// イベントリスナー登録 | |
getServer().getPluginManager().registerEvents(this, this); | |
} | |
/** | |
* ブロックを壊したときに呼び出されるメソッド | |
* @param event | |
*/ | |
@EventHandler | |
public void onBlockBreak(BlockBreakEvent event) { | |
// ブロックを壊したのがサバイバルモードのプレイヤーで、 | |
// 壊したブロックが原木なら、イベントをキャンセルして再帰処理に突入する。 | |
Block block = event.getBlock(); | |
if ( event.getPlayer().getGameMode() == GameMode.SURVIVAL | |
&& (block.getType() == Material.LOG || block.getType() == Material.LOG_2) ) { | |
event.setCancelled(true); | |
chop(block, true, event.getPlayer().getItemInHand(), | |
getSpecies(block), new ArrayList<Location>()); | |
} | |
} | |
/** | |
* 対象のブロックが原木・葉かどうかを調べて、原木・葉なら破壊しつつ、 | |
* 周りのブロックにも同様のことを実行する。 | |
* @param block 対象ブロック | |
* @param woodCheck 原木をチェック対象にするかどうか | |
* @param tool この原木ブロックをきこるツール | |
* @param data きこる木の種類 | |
* @param checkList 再帰処理探索済みのLocationのチェックリスト | |
*/ | |
private void chop(Block block, boolean woodCheck, | |
final ItemStack tool, final TreeSpecies data, final List<Location> checkList) { | |
final Material material = block.getType(); | |
// 対象ではないブロックの種類なら、何もしない。 | |
if ( woodCheck ) { | |
if ( !isLog(material) && !isLeaves(material) ) { | |
return; | |
} | |
} else { | |
if ( !isLeaves(material) ) { | |
return; | |
} | |
} | |
// 既にチェック済みなら、何もしない。 | |
if ( checkList.contains(block.getLocation()) ) { | |
return; | |
} | |
// チェック済みの地点として記録 | |
checkList.add(block.getLocation()); | |
final TreeSpecies species = getSpecies(block); | |
// 違う種類の木なら、何もしない。 | |
if ( species != data ) { | |
return; | |
} | |
// チェック最大値を超えているなら、何もしない。 | |
if ( checkList.size() > MAX_CHECK_NUM ) { | |
return; | |
} | |
// 対象のブロックを破壊する | |
block.breakNaturally(tool); | |
// 1tick遅延させてから、周りのブロックにも実行する(再帰処理) | |
new BukkitRunnable() { | |
public void run() { | |
boolean woodCheck = isLog(material); | |
chop(block.getRelative(BlockFace.NORTH), woodCheck, tool, data, checkList); | |
chop(block.getRelative(BlockFace.EAST), woodCheck, tool, data, checkList); | |
chop(block.getRelative(BlockFace.SOUTH), woodCheck, tool, data, checkList); | |
chop(block.getRelative(BlockFace.WEST), woodCheck, tool, data, checkList); | |
chop(block.getRelative(BlockFace.UP), woodCheck, tool, data, checkList); | |
// アカシア木なら、さらに斜め上も確認する | |
if ( species == TreeSpecies.ACACIA && isLog(material) ) { | |
Block up = block.getRelative(BlockFace.UP); | |
chop(up.getRelative(BlockFace.NORTH), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.NORTH_EAST), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.EAST), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.SOUTH_EAST), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.SOUTH), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.SOUTH_WEST), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.WEST), woodCheck, tool, data, checkList); | |
chop(up.getRelative(BlockFace.NORTH_WEST), woodCheck, tool, data, checkList); | |
} | |
} | |
}.runTaskLater(this, 1); | |
} | |
/** | |
* 対象のブロックが原木かどうかを調べる | |
* @param block ブロック | |
* @return 原木かどうか | |
*/ | |
private boolean isLog(Material material) { | |
return material == Material.LOG || material == Material.LOG_2; | |
} | |
/** | |
* 対象のブロックが葉ブロックかどうかを調べる | |
* @param block ブロック | |
* @return 葉ブロックかどうか | |
*/ | |
private boolean isLeaves(Material material) { | |
return material == Material.LEAVES || material == Material.LEAVES_2; | |
} | |
/** | |
* ブロックの木の種類を返す | |
* @param block ブロック | |
* @return 木の種類 | |
*/ | |
@SuppressWarnings("deprecation") | |
private TreeSpecies getSpecies(Block block) { | |
if ( block.getType() == Material.LOG_2 || block.getType() == Material.LEAVES_2 ) return TreeSpecies.ACACIA; | |
return TreeSpecies.getByData((byte) (block.getState().getData().getData() & 3)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment