Minecraft(我的世界)中文论坛

 找回密码
 注册(register)
查看: 4742|回复: 32

[插件开发教程] 插件控制合成与取消合成事件

[复制链接]
发表于 2015-9-23 18:54:17 | 显示全部楼层 |阅读模式

您尚未登录,立即登录享受更好的浏览体验!

您需要 登录 才可以下载或查看,没有帐号?注册(register)

x
本帖最后由 a390807154 于 2017-5-20 18:42 编辑

插件控制合成与取消合成事件
怎么说呢,这是个并没有卵用的教程
目地: 用插件添加新的合成 并且限制合成材料必须是用特殊数据值的
                                                                     因为Bukkit的合成只检测物品ID不检测物品的数据值
本教程说明: 类  包  方法

添加合成:
  方法 Bukkit.addRecipe(Recipe) 可以将一个Recipe进行注册是玩家能在服务器中合成
  注意 这个注册在插件被卸载的时候不会被注销 必须手动注销
  Recipe有3个子类 它们位于 org.bukkit.inventory 下 分别是: FurnaceRecipe   熔炉合成
                                                                                      ShapedRecipe    有型合成
                                                                                      ShapelessRecipe 无形合成
FurnaceRecipe : 通过查询API可知,熔炉的合成在构建的时候使用参数来设定目标物品  ←不是本教程重点ShapedRecipe : 在构建的时候通过参数ItemStack设置合成结果
ShapelessRecipe : 在构建的时候通过参数ItemStack设置合成结果


ShapedRecipeShapelessRecipe 的区别:
ShapelessRecip 只需要通过 .addIngredient() 来设置原料 无需设置形状
ShapedRecipe 必须通过 .shape(String[] shape) 来设置形状
例子:
  1. ShapedRecipe sr = new ShapedRecipe(item);
  2.         sr.shape(new String[]{
  3.                     "A C",
  4.                     "CBA",
  5.                     "A C"
  6.                 });
复制代码
那么 这个合成就必须按照这个形状来合成 不需要物品的地方使用空格

在指定形状后还需要指定每个字符代表的物品 空格不用指定
通过 .setIngredient(char key, Material ingredient) 来设置每个字符所代表的物品 因为这个方法不能使用 ItemStack 所以原料是无数据值的
例子:
  1. sr.setIngredient('A', Material.PAPER);
  2. sr.setIngredient('B', Material.VINE);
  3. sr.setIngredient('C', Material.BROWN_MUSHROOM);
复制代码
最后将这个合成进行注册就可以使用了
getServer().addRecipe(sr);

无形合成例子:
  1. ShapelessRecipe sr = new ShapelessRecipe(item);
  2.             sr.addIngredient(9, Material.VINE);
复制代码
就是这么简单 上面是9个藤蔓合成物品 可以重复调用方法来设置多种物品.


重点-限制合成原料必须是带有特定数据的:
此方法需要一个监听器: CraftItemEvent

在监听器中写入
  1. ItemStack item = evt.getRecipe().getResult();
  2.         item.setAmount(1);
  3. if (item.equals(目标物品)) {
  4.             if (!evt.getInventory().contains(必须原料)) {
  5.                 evt.setCancelled(true);
  6.             }
  7. }
复制代码


本教程到此为止 如果有更好方法请在下面回复~

↓ 加人气不扣自己的哦

下页 实例代码

评分

参与人数 10人气 +11 金粒 +22 贡献 +1 收起 理由
zide888@qq.com + 1 MCBBS有你更精彩~
byxiaobai + 1 很棒的作品!
吕乐乐 + 1 楼主你太帅了~
黄总 + 1 + 2 楼主你太帅了~
bole1314 + 1 楼主你太帅了~
纯白剑姬 + 1 Mcbbs有你更精彩~
SYS_TEM + 2 Mcbbs有你更精彩~
深蓝の回忆 + 1 Mcbbs有你更精彩~
RecursiveG + 1 + 20 + 1 已加入教程全家桶
qq568129016 + 1 Mcbbs有你更精彩~

查看全部评分

 楼主| 发表于 2015-9-24 18:03:59 | 显示全部楼层
本帖最后由 a390807154 于 2015-9-26 17:16 编辑

已经更新原内容
回复

使用道具 举报

发表于 2015-9-26 10:03:31 来自手机 | 显示全部楼层
感谢楼主,我上次就想问这个问题
回复

使用道具 举报

发表于 2015-11-21 23:04:22 | 显示全部楼层
弱弱问句 这个合成的

不卸载有什么关系?

Jre在结束的时候不是会自动回收吗
回复

使用道具 举报

 楼主| 发表于 2015-11-22 08:44:01 | 显示全部楼层
Event 发表于 2015-11-21 23:04
弱弱问句 这个合成的

不卸载有什么关系?

话说我没卸载这个监听器吧
回复

使用道具 举报

发表于 2015-11-22 09:55:25 | 显示全部楼层
福音啊,感谢楼主写此教程
回复

使用道具 举报

发表于 2016-3-14 15:35:13 | 显示全部楼层
能设置所需物品数量么
回复

使用道具 举报

 楼主| 发表于 2016-3-14 18:14:00 | 显示全部楼层
494308843 发表于 2016-3-14 15:35
能设置所需物品数量么

物品数量请通过CraftItemEvent事件获取CraftingInventory后自行分析是否达到物品数量要求

大部分的条件都要通过这步实现

建议你设置一个ItemStack[]为必要的物品 然后进行对比

评分

参与人数 1人气 +1 收起 理由
494308843 + 1 Mcbbs有你更精彩~

查看全部评分

回复

使用道具 举报

发表于 2016-3-14 22:19:48 | 显示全部楼层
如果有同ID自定义lore物品  合成不同的物品
怎么弄
合成摆放一样
回复

使用道具 举报

 楼主| 发表于 2016-3-15 06:54:11 | 显示全部楼层
494308843 发表于 2016-3-14 22:19
如果有同ID自定义lore物品  合成不同的物品
怎么弄
合成摆放一样

因为CraftItemEvent是继承InventoryClickEvent的

所以你可以通过InventoryClickEvent事件的方法将合成的结果物品替换掉(在拿起物品的时候)

setCurrentItem(ItemStack stack)方法来实现
回复

使用道具 举报

发表于 2016-3-17 13:34:55 | 显示全部楼层
{:10_494:}怎么卸载
我复制你插件的卸载代码
发现无效
然后测试你插件
卸载插件
发现
也无效
回复

使用道具 举报

发表于 2016-3-17 13:37:18 | 显示全部楼层
a390807154 发表于 2016-3-15 06:54
因为CraftItemEvent是继承InventoryClickEvent的

所以你可以通过InventoryClickEvent事件的方法将合成的 ...

这个方法有毒!为什么玩家点击自己背包能触发
也能获取物品
但是!修改物品  也成功了!
LORE我输出  也是修改了
但是物品就是没变!
但是在箱子就一切正常!
回复

使用道具 举报

 楼主| 发表于 2016-3-17 18:06:02 | 显示全部楼层
请不要直接监听InventoryClickEvent事件
请监听CraftItemEvent事件并使用他的父方法

另外你是要卸载什么
卸载合成的话https://coding.net/u/Bryan_lzh/p/SuperBandage/git/blob/master/src/superbandage/SuperBandage.java

回复

使用道具 举报

发表于 2016-3-17 20:50:48 | 显示全部楼层
我调试了好久
发现
迭代器获得的Recipe
equals
不能比较
唯一能比较的只有结果物品
但是如果有合成结果相同 不同公式的  没法确定是哪一个
强制转换为对应的
比如(ShapedRecipe)
getShape
这个获取到的String数组
好像次次都是
abc
d..
...这样的
不能用来对比
但是这确实是之前添加的合成
太蛋疼了

不知道我测试的有问题没
具体该怎么弄才能移除指定的合成


回复

使用道具 举报

 楼主| 发表于 2016-3-17 21:07:04 | 显示全部楼层
494308843 发表于 2016-3-17 20:50
我调试了好久
发现
迭代器获得的Recipe

看来应该是合成被注册后被修改了呢

那么在下这里给你提供一个解决方案

合成出的目的物品在设置时先设置为不同Lore的

最后通过事件在取出的时候替换 这样能做到合成出相同的物品
而且能够通过Bukkit.getRecipesFor()方法来寻找那个要卸载的合成

评分

参与人数 1人气 +2 收起 理由
494308843 + 2 编程果然是要灵活啊= =

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册(register)

本版积分规则

Archiver|小黑屋|Mcbbs.net ( 京ICP备15023768号-1 ) | 手机版本

GMT+8, 2018-11-17 20:55 , Processed in 0.137605 second(s), 22 queries , Memcache On.

"Minecraft"以及"我的世界"为Mojang Synergies AB的商标。本站与Mojang以及微软公司没有从属关系。

© 2010-2019 我的世界中文论坛 版权所有。本站原创图文内容版权属于原创作者,未经许可不得转载。

快速回复 返回顶部 返回列表