用worldedit的確可以達成同樣的目標,可是那又太容易了。這個fastbuild的目標,就是一個威力中等的plugin,不像worldedit這麼有破壞力,保留建築材料自己取得的挑戰,又比用鐵鏟跟專注狂點右鍵更快一些,可以把精力用在建築物的設計上。
總結來說,worldedit是要讓creative mode更creative mode;fastbuild則是要讓survival mode 更creative mode一點。
雖然已經有人寫過了類似的東西,在參考資料[1],但它是mod,也沒有繼續更新,大體上我的目標和它是一樣的。
本plugin的spec如下:
1. 使用某個鍵或指令,目前設定是setn int,讀入使用者打入的數字。2. 之後破壞方塊和放置方塊時,可以一次破壞/放置該數字的方塊。
3.破壞/放置方塊時的方向,視破壞/放置方塊哪個面而定,破壞上面,就是向下破壞n格;放置上面,就是向上放置n格。
4. 破壞方塊時,該數字目前先定在64,輸入超過數字會自動設在64。
5. 破壞方塊時,若n格內有空氣方塊,則破壞會穿過該格空氣。
6. 破壞方塊時,工具也會進行n次耐久減損判定,所以工具也要帶夠。
7. 破壞方塊時,若用鏟子挖土,但n格內可能有岩石,這要視bukkit怎麼設計。
8. 放置方塊時,該數字同樣先定在64,或者是放置時該stack所持有的方塊數量。
9. 放置方塊時,若遇到其他方塊擋路,則只放到擋路方塊為止。
10. 若以向上跳後向下放置方塊,一次放3個以上的方塊,可能會有窒息的風險或無法放置,這裡不處理。
11. 不支援復原,蓋錯了就要自己打掉,拆錯了自己建回去,科科科。
實際設計:
開發minecraft,想到java;提到java,想到Sun;說到Sun,想到eclipse(誤)。 主要參考minecraft bukkit server的文件[2],步驟很詳細沒遇上太多問題。package name: io.github.yodalee.FastBuild
照tutorial 的步驟,創建FastBuild class,用FastBuildSetnCmd接受setn command,用hashedMap記錄每一個玩家目前設定的值。
Event Handler是主要要寫的地方,這裡就要參閱bukkit API的文件,我們這裡要處理的,大部分是在org.bukkit.event.block之下,像放置block的org.bukkit.event.block.BlockPlaceEvent,我們就是要處理這個事件。
@EventHandler public void onPlace(BlockPlaceEvent event){ }這樣就可以處理這個事件,看看要幹什麼。
例如BlockPlaceEvent這個class裡面有一個setCancelled的function,用來設定這個event要不要被bukkit處理,如果我們這樣寫
@EventHandler public void onPlace(BlockPlaceEvent event){ event.setCancelled(true); }那這個server就再也不能蓋東西了ww。 或者可以玩一點更勁爆的
@EventHandler public void onPlace(BlockPlaceEvent event) { Player player = event.getPlayer(); Block block = event.getBlockPlaced(); if (block.getType() == Material.DIAMOND_BLOCK) { player.getWorld().strikeLightning(player.getLocation()); } }算是某種禁奢條款,只要放置鑽石方塊想炫富就會被雷劈XD。
回到正題,我們要做的,其實就是從這個place Event裡,取出玩家放置的位子、方位,然後用for loop 重複呼叫placeBlockEvent即可。 目前bukkit好像無法呼叫「在某地放置方塊」的function,因此先用setType來實作,直接取代方塊。
Player player = event.getPlayer(); Block block = event.getBlockPlaced(); Block againstBlock = event.getBlockAgainst(); BlockFace face = againstBlock.getFace(block); Block nextBlock = null; ItemStack stackInHand = event.getItemInHand(); int stackAmount = stackInHand.getAmount(); int n,i; //get n if (plugin.playerN.containsKey(player)) { n = plugin.playerN.get(player); } else { n = 1; } n = Math.min(n, stackAmount); stackInHand.setAmount(stackInHand.getAmount() -1); //build if (face != null) { for ( i = 0 ; i < n-1 ; i++) { nextBlock = block.getRelative(face); if (checkReplaceable(nextBlock)) { nextBlock.setType(stackInHand.getType()); block = nextBlock; } else { break; } } } // reduce itemStack in hand if (player.getGameMode() != GameMode.CREATIVE) { stackInHand.setAmount(stackInHand.getAmount() - n); player.setItemInHand(stackInHand); }Build大體上的實作就是這樣,其實不算太難。 Break的部分,因為牽扯到手中工具耐久的問題,也許下次再來寫=w=。
Demo:
原始碼:
本程式公開所有原始碼,歡迎修改後丟pull
request,這樣我也不用想break方塊怎麼寫了(誤)
https://github.com/lc85301/FastBuild參考資料:
1. minecraft mod fastbuildhttp://www.youtube.com/watch?v=yT5zaBC9O_U
2. bukkit Plugin Tutorial
http://wiki.bukkit.org/Portal:Developers
3. YAML definition
http://wiki.bukkit.org/Plugin_YAML
4. Bukkit API Overview,喔這妖受好用的
http://jd.bukkit.org/
沒有留言:
張貼留言