作者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)
1F:推 jacky951:开发推! 03/10 01:36
2F:推 XDglory:热心推!!! 03/10 01:45
3F:推 turtleee:超屌的!!!!! 03/10 01:56
4F:→ aresa:/gamemode player 1 03/10 02:22
5F:推 mion0723:这是作弊啊... ((测试中 03/10 02:24
6F:推 yeh19921026:/gamemode dhan 1 03/10 04:23
7F:推 vencin1987:server端呢? 最近觉得每次都要把发射器塞满箭 03/10 04:40
8F:→ vencin1987:实在是太麻烦了 想改没装东西就是射箭 03/10 04:41
9F:→ vencin1987:像这种也是要CLIENT、SERVER两边改吗?另应该可以用 03/10 04:42
10F:→ vencin1987:ECLIPSE改吧? 03/10 04:42
11F:推 qmaper:请推出懒人包~XD 03/10 08:27
12F:推 aids61517:个人比较不推荐加在原本的档案中,因为复原的比较麻烦 03/10 09:03
13F:→ aids61517:从原本的档案改势必到时後又要丢进MineCraft.jar中 03/10 09:04
14F:→ aids61517:假如之後使用者装其他的Mod,而可能新增的物品ID冲突到 03/10 09:04
15F:→ aids61517:到时後要移除又比较麻烦,如果没有备份原本的class档 03/10 09:05
16F:→ aids61517:可能就是要重灌MC了 03/10 09:05
17F:推 ThunderBlade:请问像这些改动要放到多人的话应该要改伺服器端的哪 03/10 09:52
18F:→ ThunderBlade:边呢? 03/10 09:52
19F:→ j022015:推一个~ 03/10 09:54
21F:推 ThunderBlade:楼上感激不尽 03/10 10:19
22F:推 T91:作壁阿XDDD 03/10 10:29
23F:推 l17:收录 03/10 16:26
24F:推 lover19:根本土制炸弹... 03/10 18:53
25F:推 zseineo:推 03/10 20:06