本帖最后由 liach 于 2019-4-15 13:18 编辑

/data modify——不用一秒钟,批量驯服宠物!


有没有想过在 Minecraft 中过上后宫宠物三千的日子,但又懒得一只一只驯?1.14 最新命令能完成你的愿望!

原先……一群恶狼看到一只美味的肥羊,凶猛地扑了上去!


一秒钟以后……



原先的羊羊尸骨未寒没看到左边的羊毛和地上的生肉吗,一群饿狼就全变成了乖狗狗!



众所周知,在 1.14 中 Minecraft 又添加了更多命令和战利品上的技术性内容,尤其是
  1. /loot
  2. /data modify
复制代码
两个让人尤其喜闻乐见的指令。

/data modify
/data modify 大致相当于 /execute store <entity/block> 的一个替代版本(同样是只能抄到一个实体上),可以把 NBT 中的数据从一个(方块)实体复制到另一个(方块)实体。
然而 /data modify 可以复制 NBT 字符串!这也是它可以设置宠物类生物 NBT 中主人标签所必须的属性(主人标签是字符串形式的一个 UUID)

但是就算能复制 UUID 字符串,这个 UUID 字符串哪里来?
根据英文 Minecraft Wiki 玩家数据页所述,玩家 NBT 数据中只有 UUIDLeast 和 UUIDMost,没有现成的 UUID 字符串。所以从玩家身上抄数据是行不通的。

那么有什么东西可以自动补齐玩家 UUID 字符串呢?
老司机不用问就知道用玩家头可以获得玩家皮肤 Base 64 码和 UUID 信息。喜闻乐见的是,玩家头里面的 UUID 也是字符串,可以直接抄到宠物身上!
但是……要让玩家头颅自动补齐数据,也需要把玩家的用户名放进 NBT 里面。而玩家 NBT 数据中也没有玩家用户名,所以……卡壳了?

等等!我们有战利品表!
在 1.14 中,战利品表函数中新增了一个 minecraft:fill_player_head 可以根据发送命令的玩家实体生成一个对应的头颅。这样我们就好办了!
(注意:这里 /loot 执行时执行实体必须是玩家才能正确获得头!在 /execute 中使用时小心)

战利品要怎么放?
在 1.14 中,/loot 命令可以把战利品在世界中生成,或者把战利品放在能存贮物品的(方块)实体中,或者直接给玩家。

为了安全起见(避免和游戏中正常方块/实体冲突),我选择把战利品放在一个实体中。
虽然 /loot spawn 可以直接刷出一个物品实体,但是无法添加 NBT 标签,会导致它可以被玩家捡起,会受伤,等等。所以不使用此方法。
剩下就 /loot give 和 /loot insert 了。我选择 /loot insert,这样好知道物品会放在哪个格子中,方便抄 NBT。

战利品要放哪个实体上?
这里相对比较自由了。我最早选择放盔甲架头部格子(又是什么都用盔甲架的流水线作业),感觉比较方便。
但是我后来为了性能考虑改用物品展示框,将头放到物品展示框的唯一一格中(可以用 hotbar.0),在 NBT 格式中存在根 NBT 中的 Item 这个 NBT 对象里面。
如果你需要缓存头颅的实体完全看不见,可以考虑箱子矿车,不会渲染背包里面的物品。
当然你最好加个记分板标签,这样作为宠物找有数据的实体找起来比较简单,最后把这个实体删除也简单。

怎么抄?
我们有一群宠物,但是 /data modify 和 /execute store 都只能有一个被修改的目标。幸亏 Minecraft 有 /execute 和命令函数,可以用 /execute 把多个宠物中每一个作为命令执行者,把数据从带着头颅的实体上抄过来,这样就不怕一个被修改的目标的限定了。数据路径啊……宠物的 UUID 是自己的 OwnerUUID 字段,头颅的 UUID 是在物品 NBT 对象根目录底下的 tag.SkullOwner.Id 里面。实在不懂就看看下面宠物抄数据的函数内容吧。

技术听懂,来看看代码吧
这个小例子放在了 GitHub 上。
主函数
可以把这里的选择器的 type 参数里面换成 entity type tag(实体类型数据包标签),这样你可以就用数据包标签套用模板了。阿猫阿狗一起驯
为了更真实,这里限定只有 20 格以内的宠物会被驯服,有兴趣请改掉。
每个宠物抄数据的函数
用来拿头颅的战利品表

说这么多,这东西到底有什么实际用途
以后原版伪 mod (数据包 + 资源包、地图)可以加个物品一键驯服大批宠物之类的。
没人愿意玩原版模组,还要给每个世界装,烦
那么等你下次玩原版 PvP 地图,对面玩家放个技能把你的狗全部变成他的,你被狗咬死的时候你就知道了。

欢迎评论,有问题或建议楼主会回复!


[groupid=1496]MC百科[/groupid]