Minecraft(我的世界)中文论坛
标题: 插件控制合成与取消合成事件
作者: Bryan33 时间: 2015-9-23 18:54
标题: 插件控制合成与取消合成事件
本帖最后由 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设置合成结果
ShapedRecipe与ShapelessRecipe 的区别:
ShapelessRecip 只需要通过 .addIngredient() 来设置原料 无需设置形状
ShapedRecipe 必须通过 .shape(String[] shape) 来设置形状
例子:
- ShapedRecipe sr = new ShapedRecipe(item);
- sr.shape(new String[]{
- "A C",
- "CBA",
- "A C"
- });
复制代码 那么 这个合成就必须按照这个形状来合成 不需要物品的地方使用空格
在指定形状后还需要指定每个字符代表的物品 空格不用指定
通过 .setIngredient(char key, Material ingredient) 来设置每个字符所代表的物品 因为这个方法不能使用 ItemStack 所以原料是无数据值的
例子:
- sr.setIngredient('A', Material.PAPER);
- sr.setIngredient('B', Material.VINE);
- sr.setIngredient('C', Material.BROWN_MUSHROOM);
复制代码 最后将这个合成进行注册就可以使用了
getServer().addRecipe(sr);
无形合成例子:
- ShapelessRecipe sr = new ShapelessRecipe(item);
- sr.addIngredient(9, Material.VINE);
复制代码 就是这么简单 上面是9个藤蔓合成物品 可以重复调用方法来设置多种物品.
重点-限制合成原料必须是带有特定数据的:
此方法需要一个监听器: CraftItemEvent
在监听器中写入- ItemStack item = evt.getRecipe().getResult();
- item.setAmount(1);
- if (item.equals(目标物品)) {
- if (!evt.getInventory().contains(必须原料)) {
- evt.setCancelled(true);
- }
- }
复制代码
本教程到此为止 如果有更好方法请在下面回复~
↓ 加人气不扣自己的哦
下页 实例代码
https://coding.net/u/Bryan_lzh/p/SuperBandage/git/blob/master/src/superbandage/ItemsCreater.java
↑ 来自插件 http://www.mcbbs.net/thread-505610-1-1.html
合成注册部分:
- ItemStack item = new ItemStack(Material.PAPER);
- ItemMeta im = item.getItemMeta();
- im.setLore(this.Lore);
- im.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&b初级绷带"));
- item.setItemMeta(im);
- ShapedRecipe sr = new ShapedRecipe(item);
- sr.shape(new String[]{
- "M M",
- "M M",
- "M M"
- });
- sr.setIngredient('M', Material.VINE);
- Items.plugin.getServer().addRecipe(sr);
- Items.plugin.sr.add(sr);
- return item;
复制代码 对应合成:
- ItemStack item = new ItemStack(Material.PAPER);
- ItemMeta im = item.getItemMeta();
- im.setLore(this.Lore);
- im.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&b中级绷带"));
- item.setItemMeta(im);
- ShapedRecipe sr = new ShapedRecipe(item);
- sr.shape(new String[]{
- "MPM",
- " G ",
- "M M"
- });
- sr.setIngredient('M', Material.VINE);
- sr.setIngredient('G', Material.GOLD_INGOT);
- sr.setIngredient('P', Material.PAPER);
- Items.plugin.getServer().addRecipe(sr);
- Items.plugin.sr.add(sr);
- return item;
复制代码 对应合成:
监听部分:
https://coding.net/u/Bryan_lzh/p/SuperBandage/git/blob/master/src/superbandage/S_BandageListener.java
作者: Bryan33 时间: 2015-9-24 18:03
本帖最后由 a390807154 于 2015-9-26 17:16 编辑
已经更新原内容
作者: 可可可可可乐 时间: 2015-9-26 10:03
感谢楼主,我上次就想问这个问题
作者: CatSeed 时间: 2015-11-21 23:04
弱弱问句 这个合成的
不卸载有什么关系?
Jre在结束的时候不是会自动回收吗
作者: Bryan33 时间: 2015-11-22 08:44
话说我没卸载这个监听器吧
作者: 深蓝の回忆 时间: 2015-11-22 09:55
福音啊,感谢楼主写此教程
作者: 494308843 时间: 2016-3-14 15:35
能设置所需物品数量么
作者: Bryan33 时间: 2016-3-14 18:14
物品数量请通过CraftItemEvent事件获取CraftingInventory后自行分析是否达到物品数量要求
大部分的条件都要通过这步实现
建议你设置一个ItemStack[]为必要的物品 然后进行对比
作者: 494308843 时间: 2016-3-14 22:19
如果有同ID自定义lore物品 合成不同的物品
怎么弄
合成摆放一样
作者: Bryan33 时间: 2016-3-15 06:54
因为CraftItemEvent是继承InventoryClickEvent的
所以你可以通过InventoryClickEvent事件的方法将合成的结果物品替换掉(在拿起物品的时候)
setCurrentItem(ItemStack stack)方法来实现
作者: 494308843 时间: 2016-3-17 13:34
{:10_494:}怎么卸载
我复制你插件的卸载代码
发现无效
然后测试你插件
卸载插件
发现
也无效
作者: 494308843 时间: 2016-3-17 13:37
这个方法有毒!为什么玩家点击自己背包能触发
也能获取物品
但是!修改物品 也成功了!
LORE我输出 也是修改了
但是物品就是没变!
但是在箱子就一切正常!
作者: Bryan33 时间: 2016-3-17 18:06
请不要直接监听InventoryClickEvent事件
请监听CraftItemEvent事件并使用他的父方法
另外你是要卸载什么
卸载合成的话https://coding.net/u/Bryan_lzh/p/SuperBandage/git/blob/master/src/superbandage/SuperBandage.java
作者: 494308843 时间: 2016-3-17 20:50
我调试了好久
发现
迭代器获得的Recipe
equals
不能比较
唯一能比较的只有结果物品
但是如果有合成结果相同 不同公式的 没法确定是哪一个
强制转换为对应的
比如(ShapedRecipe)
getShape
这个获取到的String数组
好像次次都是
abc
d..
...这样的
不能用来对比
但是这确实是之前添加的合成
太蛋疼了
不知道我测试的有问题没
具体该怎么弄才能移除指定的合成
作者: Bryan33 时间: 2016-3-17 21:07
看来应该是合成被注册后被修改了呢
那么在下这里给你提供一个解决方案
合成出的目的物品在设置时先设置为不同Lore的
最后通过事件在取出的时候替换 这样能做到合成出相同的物品
而且能够通过Bukkit.getRecipesFor()方法来寻找那个要卸载的合成
作者: hhttll 时间: 2016-5-4 09:50
受教了谢谢
作者: jkaa13579 时间: 2016-5-28 16:44
解决了无MOD无法自定义合成公式的问题,感谢楼主兼版主
作者: chenzizai 时间: 2016-7-21 09:21
请问FurnaceRecipe 熔炉合成怎么写
作者: Bryan33 时间: 2016-7-21 12:19
利用构建方法
FurnaceRecipe(ItemStack result, Material source)
来指定生成的物品和烧制之前的物品
烧的时间不能指定
然后直接用Bukkit.addRecipe(Recipe recipe);来添加
作者: chenzizai 时间: 2016-7-23 12:33
能不能举两个代码例子:
石砖烧成裂石砖
多个物品无形合成:藤蔓+园石=苔石
作者: Bryan33 时间: 2016-7-23 13:21
帖子第二页有有型合成的
这种东西需要你自己手动写代码去摸索的
作者: User:guest 时间: 2016-12-4 17:53
感谢楼主提供的菜谱自定义技术分享。请问Recipe接口这里,实例化时是用实现它的实现类吗
作者: Bryan33 时间: 2016-12-5 22:39
对
构建他的子类new
作者: byxiaobai 时间: 2017-1-14 11:53
感谢楼主,666啊
作者: 拉普达 时间: 2017-2-11 03:01
楼主我是小白
想问您一些问题
这是我写的代码
应该如何制定leather的合成材料腐肉名字必须是§6烧制腐肉?
否则不能合成


作者: Bryan33 时间: 2017-2-11 17:50
物品不能使用equals方法
而要使用isSimilar方法
另外 可以通过item.getItemMeta().getDisplayName()来获取物品的名字
建议先用item.getItemMeta().hasDisplayName()来判断是否有名字
- if(item.getItemMeta().hasDisplayName()&&item.getItemMeta().getDisplayName().equalsIgnoreCase("§6烧制腐肉")){
- //TODO}
复制代码
作者: 拉普达 时间: 2017-2-11 20:20

腐肉经过烧制得到命名"§6烧制腐肉"的腐肉
然后再用腐肉与线合成皮革
前面我通过你的教程研究写好了
但是我想要腐肉的名字必须为§6烧制腐肉才可以合成皮革
作者: Bryan33 时间: 2017-2-11 22:20
- @EventHandler
- public void onCraft(CraftItemEvent evt) {
- if (evt.getRecipe().getResult().isSimilar(leather)) {
- for (ItemStack is : evt.getInventory().getMatrix()) {
- if (is.getType() == Material.ROTTEN_FLESH && is.hasItemMeta() && is.getItemMeta().hasDisplayName()) {
- if (!is.getItemMeta().getDisplayName().equals("§6烧制腐肉")) {
- evt.setCancelled(true);
- return;
- }
- }
- }
- }
- }
复制代码
作者: Kyokuki 时间: 2018-8-23 16:55
不是我说,写的一点都不清楚,萌新是看不明白的,不推荐
作者: Bryan33 时间: 2018-8-24 09:37
抱歉了 这个教程不是给没有任何基础的人看的
作者: gooding300 时间: 2018-8-24 18:46
本帖最后由 gooding300 于 2018-8-24 20:07 编辑
作者您好,有个问题想请教一下,用这个方法修改的合成表可以同步到客户端吗?
(例如原版自带的合成书中能否看到变更后的合成表?)
或者是CraftGuide、NEI、JEI等可以显示合成表的mod
作者: Bryan33 时间: 2018-8-24 20:01
抱歉啊
因为这个教程是很早之前写的
那个时候客户端还没有合成书之类的东西
所以我也没有测试过
作者: Bryan33 时间: 2018-8-25 21:28
测试了一下原版的合成书
发现 如果你删除了服务端的合成配方
客户端不会显示任何配方
自定义的配方也不会显示在其中
作者: Sssss... 时间: 2020-3-17 17:36
补充:现在的ShapedRecipe已经有实例方法setIngredient(char, ItemStack)了(好像很久以前就有了)
作者: lxf2051703348 时间: 2020-3-19 10:56
支持一下,感谢分享
作者: lxf2051703348 时间: 2020-3-19 10:59
为啥1.12.2没有
作者: Sssss... 时间: 2020-3-19 11:46
不知道,反正1.13是有的