這篇接續上一篇
最近花了一點時間,把fastbuild plugin本來預定的功能寫完了。
至於為什麼會相隔這麼久(16天),因為作者平常都在打東方有很多事情要忙,加上Java實在不是作者熟悉的語言,以致進度緩慢。
這次主要寫的是break的部分,原始碼比place 的listener多了一倍,因為break還涉及手中工具的耐久度設定、是否要掉下東西等,功能更複雜。
廢話不多說,來看看怎麼設計。
Event Handler
首先我們要聲請監聽票的event是BlockBreakEvent,這個event會在block被破壞的時候呼叫。 這個event會包含資訊有:玩家,被破壞的方塊。
為了要做到fastbuild的功能,我另外監看了PlayerInteractEvent,可以從這個事件中取得,玩家是碰到方塊的哪一個面。
因為plugin只能做到event based,因此這個plugin還是有一點限制,我們不能讓使用者邊敲方塊,後面一整排的方塊都開始出現裂痕,只能處理BlockBreakEvent(方塊已經爆了),再把後面的方塊設成空氣。
這樣會產生一個問題:如果使用者用鏟子爆了泥土,可是後面是石頭,這樣不就可以用鏟子當超強挖礦工具?
所以這裡我們限制會一起挖的,只能是同樣類型的block。
for (int i = 0; i < n-1; i++) {
nextBlock = block.getRelative(face);
//currently only deal with same type block
if (nextBlock.getType() == originType) {
Collection drops = getDrops(tool, nextBlock);
nextBlock.setType(Material.AIR);
if (!isCreative) {
// drops
createDrops(nextBlock, drops);
// durability
if(!reduceDurability(tool,player)) {
break;
}
}
} else {
break;
}
}
Durability:
這部分參考2-3
,透過ItemStack的setDurability()
跟getDurability()
去設值,要注意的是durability值愈高表示工具愈爛,並且可以用 ItemStack.getType().getMaxDurability()
,來確定工具壞了,以免工具只能挖一格,卻把20格都挖掉了。
Enchantment:
我們處理的enchantment有unbreaking跟silk touch,分別影響durability跟drop items。
minecraft裡物品的item max durability值是恆定的,unbreaking只是在增加durability 時加上一個機率,有一定的機不扣durability,在這裡我們複製這個設定。
可以透過 ItemStack.getEnchantmentLevel(Enchantment ench);
來取得enchantment的值,非 0 表示有enchantment。
drops:
這裡我們呼叫 block.getDrops(ItemStack) 來產生drop items內容,用這個的好處是,它會自動判斷工具的等級高低,像用木鎬挖鐵礦,這個事件就會回傳空的內容。
不過它不會處理工具有Silk touch的狀況,因些有Silk touch的時候要自己把原本的方塊傳回去。
最後再利用World.dropItemNaturally(Location, ItemStack)
產生drop items即可。
Demo:
這個是用gtk-recordMyDesktop錄的,聲音好像比畫面還要慢一點,我也不知道問題在哪lol。
原始碼:
本程式公開所有原始碼,遇到bugs歡迎修改後丟pull request
FastBuild
參考資料
- Bukkit API Overview ,要寫plugin不看這個不行www
- Minecraft Wiki enchantment
- Minecraft Wiki tools