此教程介绍一个数据包制作的实例,阅读此教程前请先确保自己掌握教程/制作数据包和教程/制作资源包的知识。了解命令、记分板、原始JSON文本等页面也会有所帮助。
目标[]
动手制作一个数据包前,你应该有一个明确的目标。也许你已经阅读过很多命令教程,但是却不知道如何有机地整合这些知识。在本实例中,我们会解析如何制作一个数据包,使得玩家视线所指的地方发生爆炸。
由于教程/制作数据包/实例:蜜蜂助手中已经包含了这篇实例的一部分内容,所以本实例讲述的会较为含糊,甚至有一段全部是命令。这就需要你自己静下心来思考这些文件的关系了。
本实例的GitHub地址:点击这里
开始[]
视线所指[]
在实例:蜜蜂助手中我们已经较为清楚的描述了“视线所指”如何实现,这里仅再一次给出局部坐标的解释图。
爆炸[]
嗯,爆炸。还能多简单呢?
为了达到爆炸的目的,我们可以在所指的地方召唤一个瞬间爆炸的TNT或者苦力怕。
但是,我们也可以做的更有趣一些,比如……一个小小的世界橡皮擦,又或是加一些粒子特效。这就要看你怎么发挥了。
编写与实现[]
初始化[]
以下#<命名空间>:<名字>
表示<命名空间>下的<名字>标签,<命名空间>:<名字>
表示<命名空间>下的<名字>对象(可以是函数、模型等)。
新建一个文件夹,填写好pack.mcmeta
,建立data
文件夹。在data
文件夹下建立nuke
(本实例以此为主要的命名空间)和minecraft/tags/functions
(一些函数需要被每刻执行和在地图加载时执行)文件夹。
本实例中不使用队伍来侦测正在使用该功能的玩家(因为使用队伍可能会影响其他数据包的运作),而是使用记分项。本实例的记分项前缀为nuke
。
建立data/nuke/functions
,建立load.mcfunction
函数,内容如下:
scoreboard objectives add nukePerson dummy
scoreboard objectives add nukeUseCSt minecraft.used:minecraft.carrot_on_a_stick
第一条命令初始化了一个nukePerson
记分项,用来记录玩家是否正在使用爆炸功能,类型为dummy
,也就是只能被命令修改。
第二条命令初始化了一个nukeUseCSt
记分项,类型是……
好,你可能会问,“为什么这一次不用dummy
了”,对吧?
在原版中,胡萝卜钓竿应该算是最方便检测右键功能的物品,原因就是有这么一个准则minecraft.used:minecraft.carrot_on_a_stick
,它可以自动记录玩家use胡萝卜钓竿的次数。
没错,我们这次会使用胡萝卜钓竿作为本功能的开关(的本体)。nukeUseCSt
记分项中的“CSt”也就是“Carrot on a Stick”(胡萝卜钓竿)的缩写。我们需要这个记分项来制作这个开关。
这一次胡萝卜钓竿的检测会参照更多的合成的某个版本编写,如果目录结构过于分散可以尝试自己简化。
建立data/minecraft/tags/functions/load.json
,内容如下:
{
"replace": false,
"values": [
"nuke:load"
]
}
这样,将nuke:load
函数设定为(重新)加载时执行。
下文提及到将函数加入标签时请参照这里。
视线投射[]
在nuke
命名空间下,建立tick.mcfunction
和ray.mcfunction
函数。
tick.mcfunction
execute as @a run function nuke:entities/player
execute as @a[scores={nukePerson=1..}] at @s anchored eyes run function nuke:ray
第一条命令用于后面的胡萝卜钓竿检测。
第二条命令将执行位置对齐到头部,然后开始执行视线投射。
将nuke:tick
函数也加入#minecraft:tick
,使得其每刻执行。
ray.mcfunction
execute unless entity @s[distance=..20] positioned ^ ^ ^2 run function nuke:nuke
execute if entity @s[distance=..20] unless block ~ ~ ~ #nuke:get_through run function nuke:nuke
execute if entity @s[distance=..20] if block ~ ~ ~ #nuke:get_through positioned ^ ^ ^0.005 run function nuke:ray
好,一上来出现了很多东西,但是基本和实例:蜜蜂助手中的差不多。
#nuke:get_through
标签内储存的是视线追踪会忽略的方块,毕竟我们获取“视线所指”的方块并不想包含空气、草、花这些东西,但同时我们需要获取的也不仅仅是一类方块(不同于蜜蜂助手中我们只获取蜂巢类方块)。这个标签是自创的,也就是你需要自己整理一份/抄实例的标签列表,然后把列表放到data/nuke/tags/blocks/get_through.json
里面。
nuke:nuke
是实际执行爆炸的函数。
你会发现,这次出现了三个命令。其中两条和实例:蜜蜂助手差不多,这里不再赘述。
第一条是因为,我们并不希望我们看着天空就不会发生爆炸(也就是并没有看着任何方块的时候),所以如果视线追踪往前20格都没有碰到任何方块,那就直接再前进两格然后执行爆炸。“再前进两格”并不是必须的。
爆炸和消除[]
summon minecraft:tnt ~ ~ ~
没错,生成一个TNT,就这么简单。或者,如果你想做世界橡皮擦:
setblock ~ ~ ~ minecraft:air
到此,基本功能的逻辑就实现(但还未实装)完毕了。
你也可以生成一个会瞬间爆炸的苦力怕,甚至可以调节它的爆炸威力,但是不要尝试用隐身状态效果隐藏它——苦力怕爆炸时会生成所带的状态效果的区域效果云,这可能会导致异常的卡顿。
胡萝卜钓竿开关[]
还记得上面提到的函数nuke:entities/player
吗?
下面我会给出所有和这个胡萝卜钓竿开关相关的函数,接好了:
nuke:entities/player
execute as @s[scores={nukeUseCSt=1..}] at @s run function nuke:use_carrot_on_a_stick/type
nuke:use_carrot_on_a_stick/type
execute as @s[nbt={SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] run function nuke:use_carrot_on_a_stick/mainhand
execute as @s[nbt=!{SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] run function nuke:use_carrot_on_a_stick/offhand
scoreboard players reset @s nukeUseCSt
nuke:use_carrot_on_a_stick/mainhand
execute as @s[nbt={SelectedItem:{tag:{id:"nuke:remote"}}}] run function nuke:use_carrot_on_a_stick/items/remote
execute as @s[tag=!nuke_used,nbt={SelectedItem:{tag:{id:"nuke:remote_off"}}}] run function nuke:use_carrot_on_a_stick/items/remote_off
tag @s remove nuke_used
nuke:use_carrot_on_a_stick/items/remote_off
loot replace entity @s[nbt=!{SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] weapon.offhand 1 loot nuke:remote
loot replace entity @s[nbt={SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] weapon.mainhand 1 loot nuke:remote
function nuke:start
nuke:use_carrot_on_a_stick/items/remote
loot replace entity @s[nbt=!{SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] weapon.offhand 1 loot nuke:remote_off
loot replace entity @s[nbt={SelectedItem:{id:"minecraft:carrot_on_a_stick"}}] weapon.mainhand 1 loot nuke:remote_off
function nuke:stop
tag @s add nuke_used
nuke:start
scoreboard players set @s nukePerson 1
nuke:stop
scoreboard players set @s nukePerson 0
让我们解析一下为什么会这么写。
首先,我们得构想我们的这个胡萝卜钓竿开关——就叫遥控器好了,到底是怎么样的。
为了和普通的胡萝卜钓竿区别开来,我们会在物品的tag
中嵌入自己的id
标签(如果你不希望这个标签被其他的数据包占用,你也可以命名为类似nuke_id
),并把关闭状态的遥控器的id
的值设定为nuke:remote_off
,开启的设定为nuke:remote
。
检测玩家的SelectedItem
NBT标签就可以检测主手上的物品了。此处我们检测tag
,就是检测玩家手上有没有遥控器。
同时,因为遥控器肯定长得不像胡萝卜钓竿,所以我们需要通过CustomModelData
来重新指定遥控器的纹理。
段落内会有两个遥控器的图片(随便画的)。
新建一个资源包,填写好pack.mcmeta
,在assets/minecraft/models/item/carrot_on_a_stick.json
写入以下内容:
{
"parent": "item/handheld_rod",
"textures": {
"layer0": "item/carrot_on_a_stick"
},
"overrides": [
{ "predicate": { "custom_model_data": 13400000 }, "model": "nuke:item/remote"},
{ "predicate": { "custom_model_data": 13400001 }, "model": "nuke:item/remote_off"}
]
}
其中的overrides
就是来指定CustomModelData
的。我们指定了两个物品标签谓词,分别指定了一个CustomModelData
和它对应的模型:13400000
(对应nuke:item/remote
)和13400001
(对应nuke:item/remote_off
)。
assets/nuke/models/item/remote.json
{
"parent": "item/handheld",
"textures": {
"layer0": "nuke:item/remote"
}
}
其中nuke:item/remote
对应纹理assets/nuke/textures/item/remote.png
,也就是开启的状态的纹理。
另一个模型文件同理。
为了获取物品的方便,我们使用战利品表来预定义物品。此处以关闭的遥控器为例。
nuke:remote_off.json
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "minecraft:carrot_on_a_stick",
"functions": [
{
"function": "minecraft:set_nbt",
"tag": "{id:'nuke:remote_off',display:{Name:'{\"translate\":\"item.nuke.remote_off\"}'},CustomModelData:13400001}"
}
]
}
]
}
]
}
掉落一份该战利品表就会获得关闭状态的遥控器。除了定义tag
中的id
,我们也自定义了物品的CustomModelData
和显示名称。显示名称和实例:蜜蜂助手的多语言一样去写就行。此处在简体中文中显示的名称为“遥控器 (关闭)”。
同理,定义一份开启的。
再次回顾一遍上面的代码。现在能明白了吗?
基本思路是,循环检测胡萝卜钓竿,如果有人用了遥控器就切换遥控器的状态,并且根据遥控器的状态决定是开始爆炸还是停止爆炸。
切换遥控器的状态,可以直接替换玩家对应的槽位,比如像上方一样使用/loot replace
,然后调用定义好的战利品表,十分方便。
上方还预留了一个“offhand”,用于副手。除了使用和主手一样的使用目标选择器的NBT参数以外(但是由于副手没有提供SelectedItem
这么方便的NBT标签,我们需要读取玩家物品栏并且指定槽位),我们也可以使用1.15加入的(也就是实例:蜜蜂助手所使用的)谓词文件去判断。这个谓词的编写就让你自己尝试写吧。
至此,编写完毕。
另见[]
- ruhuasiyu的数据包制作教程
- ruhuasiyu的更多的合成数据包,其中包含大量可学习借鉴的地方
组件 |
| ||
---|---|---|---|
数据包 | |||
教程 |
|