作者dhan (Cogito Ergo Sum)
看板Minecraft
標題[教學] 自製合成recipe (by:dwi2)
時間Sat Mar 10 01:24:51 2012
好讀版:
http://0rz.tw/OqxSe
--
最近筆者不小心跌入了Minecraft的世界
['n']
但遊戲玩久了,劣根性也漸漸地浮現
(挖礦好慢,而且還要冒被creepers炸的風險!)
所以筆者就開始在網路上找尋作弊快速獲得某項資源的方法,剛好在PTT上看到有人
公開自己寫的合成mods,念頭一轉:
與其用作弊方式得到自己想要的資源,何不自己寫mod來實作自己的合成方法
(crafting recipe)來快速取得資源呢?
(寓教於樂又同時可以…科科)
minecraft forum上有一篇非常適合新手的tutorial,雖然文章內容稍微有些過時,
但筆者秉持著DIY的精神還有不專業的碼農技術能力跟著試做一次,
發現撰寫自己的合成方法其實相當簡單,只要稍微有一點點耐心,
任何人都可以辦到!
(是的,原來我也會燉雞湯寫程式)
需要的東西 Prerequisite
1.你的電腦需要有裝JDK (Java Develpement Kit)
Linux使用者 :我想你們應該都比我還懂!我就不說了XDD
Windows使用者:可以參考這篇安裝JDK,請安裝6.0以上版本!
Mac使用者 :開啟你的terminal,打javac
如果出現類似下面這張畫面的情形,代表你已經有JDK了!
若沒有的話,系統也會提示你安裝,
只要照著系統提示就會把JDK裝好了!
http://0rz.tw/JfqzT
2.基本的Java Programming Language基礎
如果只是想要快速進入狀況,馬上動手開始惡搞Minecraft的話,
稍微看一下良葛格的文章挺有用的。
Java本質
http://0rz.tw/4Svz7
Java學習筆記(上),Java學習筆記(下)
真心想要學好Java的話 (有人會為了改遊戲而認真學寫程式嘛?),
找本書來看吧!
例如Thinking in Java或Head First Java,想要深入的話可以看Effective Java。
前置工作
1. 下載Minecraft Coder Pack (MCP)
下載MCP6.0,解壓縮,放到你想要放的任何位置(假設是$WORKSPACE/mcp60)。
MCP 6.0版對應的是Minecraft 1.2.3版,如果要修改Minecraft 1.1版,
就要用MCP 5.6版(但是5.6版在decompile minecraft_server.jar時會有些問題)。
2. 擺放相關binaries
MCP的作法就是將Minecraft的binaries檔以jad和astyle等工具進行逆向工程,
反編譯並產生格式還蠻好閱讀的原始碼。所以我們要先把1.2.3版Minecraft的
應用程式相關檔案複製一份放到$WORKSPACE/jars/資料夾下. 我們所需的Mine
craft應用程式檔案在bin和resources資料夾下,Mac OS X的Minecraft應用程
式檔案資料夾在:
/Users/your_account/Library/Application Support/minecraft/
Windows的Minecraft資料夾在%AppData%/minecraft/下,%AppData%是系統變數,
例如Windows XP的是在
C:\Documents and Settings\your_account\Application Data\.minecraft
Windows Vista或Windows 7是在
C:\Users\your_account\AppData\Roaming\.minecraft
Linux的就在家目錄下
~/.minecraft
http://0rz.tw/RgYhr
把Minecraft的bin和resources資料夾(上圖)
整個複製到$WORKSPACE/mcp60/jars(下圖)
http://0rz.tw/zYYSJ
這樣前置工作就準備完成!
主要流程
使用MCP開發Minecraft mods的流程如下圖
http://0rz.tw/vjFVx
我們已經把左上角Prepare the files做完,接下來的流程就是反編譯(decompile)
成可以閱讀和修改的原始碼,然後在針對我們想要變更的地方進行修改或是實作mod
然後recompile。 同時mcp也提供很方便的工具和環境讓你直接就修改並recompile的
程式碼進行測試。 等確定修改過的Minecraft程式一切正常後,在進行obfuscation
並打包回jar檔,就可以發佈給親朋好友和全世界,將你的mods分享給大家囉!
現在開始進行逆向工作 – 反編譯(decompile)!
進入到$WORKSPACE/mcp60資料夾,輸入以下指令開始decompile
Mac OS X / Linux環境輸入:
./decompile.sh
Windows環境輸入:
decompile.bat
如果沒有出現任何錯誤,經過一段時間,反編譯好的source code會擺在
$WORKSPACE/src/下
不過decompile出來的原始碼有一些小問題,不是馬上就可以用的,如果你把剛剛
decompile出來的原始碼再compile一次並執行遊戲,會不斷地出現錯誤:
1286: Invalid framewbuffer operation
剛好這幾天Minecraft forum上有相關的討論串,有善心人士提供解法。
在src/minecraft/net/minecraft/client/Minecraft.java的第2461行,原來為
AWTGLCanvas awtglcanvas = new AWTGLCanvas();
將此行改為
Canvas awtglcanvas = new Canvas();
就可以了!(詳細原因我也不清楚,我完全是OpenGL門外漢呀!!)
自製合成方法
最近覺得Minecraft人物出生的地點太多崎嶇不平的地形,興起了用TNT炸山的念頭,
但本人個性膽小不太擅長跟creepers決戰,因此取得火藥的數量一直都很少。
這次自製合成方法,打算用最多最容易取得的資源 – 土,換取最想要取得的資源
– TNT炸藥。 而且這種合成方法可以確保TNT源源不絕,因為炸山都會炸出廢土,
土又可以拿去換TNT,根本就是超棒的正向迴路呀!
我的如意算盤是用2×2的土合成4個TNT炸藥:
http://0rz.tw/2s895
我們先從單人遊戲的部份開始改。 單人部分的合成方法藏在
src/minecraft/net/minecraft/src/CraftingManager.java
從檔名就可以看出來它是主要負責處理合成(crafting)的程式碼。
我們看一下第22行開始的地方:
1private CraftingManager()
2{
3 recipes = new ArrayList();
4 (new RecipesTools()).addRecipes(this);
5 (new RecipesWeapons()).addRecipes(this);
6 (new RecipesIngots()).addRecipes(this);
7 (new RecipesFood()).addRecipes(this);
8 (new RecipesCrafting()).addRecipes(this);
9 (new RecipesArmor()).addRecipes(this);
10 (new RecipesDyes()).addRecipes(this);
11 ...
在CraftingManager initiate時就建立許多recipes,從class名稱可以約略推敲
出他們的功用,例如RecipesTools就是負責建立工具相關的recipes,RecipesFood
就是建立食物相關的recipes,以此類推,想知道詳細內容的話可以直接看這些相關
class所在的檔案
(RecipesTools實作內容在src/minecraft/net/minecraft/src/RecipesTools.java)。
接下來:
1private CraftingManager()
2{<
3 recipes = new ArrayList();
4 ...
5 addRecipe(new ItemStack(Item.paper, 3), new Object[]
6 {
7 "###", '#', Item.reed
8 });
9 addRecipe(new ItemStack(Item.book, 1), new Object[]
10 {
11 "#", "#", "#", '#', Item.paper
12 });
可以看到這邊另外再增加個別的合成方法,因此我們可以參考這段code,
把想要加入的自製合成方法加上去!
先稍微說明一下addRecipe()這個method,addRecipe()的定義如下:
void addRecipe(ItemStack par1ItemStack, Object par2ArrayOfObj[])
它接收兩個參數: ItemStack和Object array。 回頭參照CraftingManager裡面使用
addRecipe的方法:
1addRecipe(new ItemStack(Item.book, 1), new Object[]
2 {
3 "#", "#", "#", '#', Item.paper
4 });
這個方法裡面牽涉到paper跟book兩種資源,合成方法裡面牽涉到這兩個資源的方法
就是三張紙直放合成一本書:
http://0rz.tw/vzQgC
因此addRecipe的第一個參數就是表示要被合成方法產出的資源以及數量,而後面的
Object array就是描述合成方法所需資源跟擺放方法(先描述擺放方法,再描述擺放
的資源)。
以合成書的這段code來說,我們想要產出的資源是1本書
(可以參照ItemStack.java查詢ItemStack的constructor用法)
1new ItemStack(Item.book, 1) // 合成1本書
Object array裡的前3個‘#’就是表示crafting table的每層要擺放一個#,
而這個#是什麼呢? 就是Object array裡最後兩個參數描述的:
1'#', Item.paper // 表示: '#'代表Item.paper
再看另外一個例子會更了解addRecipe()的用法,原先的TNT炸藥合成方式是
http://0rz.tw/FL4dX
CraftingManager裡合成TNT的程式碼:
1addRecipe(new ItemStack(Block.tnt, 1), new Object[]
2 {
3 "X#X", "#X#", "X#X", 'X', Item.gunpowder, '#', Block.sand
4 });
我們要產出的資源是1塊TNT
1new ItemStack(Block.tnt, 1)
合成方法是在crafting table上各層擺放如
1"X#X", "#X#", "X#X"
而‘X’和‘#’分別代表的資源是
1'X', Item.gunpowder, '#', Block.sand
‘X’代表gunpowder,‘#’代表sand
OK,這樣我們就知道如何寫增加自製的合成方法的程式碼了!
http://0rz.tw/2s895
我想要用2×2的土合成4塊TNT
1addRecipe(new ItemStack(Block.tnt, 4), new Object[]
2 {
3 "##", "##", '#', Block.dirt
4 });
至於代表資源的變數要去哪裡找定義呢? 可以參考這兩個檔案: Block.java和
Item.java,裡面列出代表近乎所有資源的static variables,可以黏在地上當
磚塊的屬於Block,其他物品類屬於Item。
接下來就是將我們剛剛改好的原始碼重新編譯為執行檔,是時候來測試了! 科科科
用terminal進入到$WORKSPACE/mcp60資料夾,輸入以下指令開始decompile
Mac OS X / Linux環境輸入:
./recompile.sh
Windows環境輸入:
recompile.bat
如果編譯沒有出現錯誤的話,應該會出現類似下面畫面的訊息
http://0rz.tw/MZFIn
測試
重新compile過的client端執行檔一樣擺在$WORKSPACE/mcp60/jars裡面,
但recompile過程並不會幫忙打包成完整的minecraft.jar檔,
mcp60很貼心的提供script,讓我們很方便地執行client端執行檔
Mac OS X / Linux環境輸入:
./startclient.sh
Windows環境輸入:
startclient.bat
接下來就可以看到熟悉的畫面啦! 不過我的目的只是要快速地取得TNT,
所以我想直接存取我正在玩的單人模式存檔。
方法也很簡單,在Linux和Mac上只要在
$WORKSPACE/mcp60/jars/下建立一個symbolic link,
連結到Minecraft應用程式資料夾下的saves/就可以了。
(這裡我不太確定Windows有沒有辦法建立symbolic link,不然就只好麻煩一點
把saves資料夾拷貝一份過來囉)
這樣用startclient.sh開啟遊戲時,就可以進入到之前玩的單人遊戲存檔內,
然後就開始快樂地合成TNT炸藥吧!
待續…
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.240.216.172
※ 編輯: dhan 來自: 111.240.216.172 (03/10 01:28)
推 jacky951:開發推! 03/10 01:36
推 XDglory:熱心推!!! 03/10 01:45
推 turtleee:超屌的!!!!! 03/10 01:56
→ aresa:/gamemode player 1 03/10 02:22
推 mion0723:這是作弊啊... ((測試中 03/10 02:24
推 yeh19921026:/gamemode dhan 1 03/10 04:23
推 vencin1987:server端呢? 最近覺得每次都要把發射器塞滿箭 03/10 04:40
→ vencin1987:實在是太麻煩了 想改沒裝東西就是射箭 03/10 04:41
→ vencin1987:像這種也是要CLIENT、SERVER兩邊改嗎?另應該可以用 03/10 04:42
→ vencin1987:ECLIPSE改吧? 03/10 04:42
推 qmaper:請推出懶人包~XD 03/10 08:27
推 aids61517:個人比較不推薦加在原本的檔案中,因為復原的比較麻煩 03/10 09:03
→ aids61517:從原本的檔案改勢必到時後又要丟進MineCraft.jar中 03/10 09:04
→ aids61517:假如之後使用者裝其他的Mod,而可能新增的物品ID衝突到 03/10 09:04
→ aids61517:到時後要移除又比較麻煩,如果沒有備份原本的class檔 03/10 09:05
→ aids61517:可能就是要重灌MC了 03/10 09:05
推 ThunderBlade:請問像這些改動要放到多人的話應該要改伺服器端的哪 03/10 09:52
→ ThunderBlade:邊呢? 03/10 09:52
→ j022015:推一個~ 03/10 09:54
推 ThunderBlade:樓上感激不盡 03/10 10:19
推 T91:作壁阿XDDD 03/10 10:29