零:写在前面

准备工具

VSCode以及DHP插件,或者其他代码工具。

minecraft测试环境,本教程使用minecraft1.20.1原版,其他版本可能有语法差别。

print.net,或其他绘图工具(非必须)。

7zip,或者其他支持压缩的软件。Windows自带的也行

需要了解

数据包的文件夹结构。

json文件格式,mcfunction文件格式。

本文在使用下划线部分可以替换为[0-9,a-z,_]字符的组合,可以自行替换。

一:开始

建立想法

我们假设想要创造的结构为一个水井,在最后放置水时会把水替换为信标,并在信标顶上填充玻璃。

创建文件夹结构

启动一次minecraft,并创建新世界(建议选用创造模式,允许作弊,超平坦,超平坦预设:虚空。)

打开世界文件夹中的datapacks文件夹,在此文件夹新建一个文件夹(教程使用了testdatapack作为名称),右击文件夹,使用vscode打开。

在目录里新建文件pack.mcmeta(数据包描述文件,必须),pack.png(数据包图标,非必须),data文件夹(数据包数据文件夹,必须)。

pack.mcmeta

vscode会使用文本编辑器打开此文件。

在文件内粘贴以下内容,并在正确的地方输入合适的内容。

{ "pack": { "pack_format": 15, "description": [ { "text": "6623" } ] }}其中6623可根据需要替换为介绍。

data文件夹和它的的子文件夹们 (仅列举功能所需的文件夹)

在data文件夹新建文件夹作为命名空间(教程使用了francium6623作为命名空间),在francium6623文件夹下新建下列文件夹:

advancements 定义进度,这里作为触发器。

functions 定义进度,这里作为触发器返回。

predicates 谓词,这里作为判断条件。

tags 标签,用于同时兼容多项。

advancements 此文件夹内文件格式为.json。

在advancements文件夹下新建test.json,粘贴以下内容:

{ "criteria": { "test": { "trigger": "minecraft:placed_block", "conditions": { "location": [ { "condition": "minecraft:reference", "name": "francium6623:test" }, { "condition": "minecraft:match_tool", "predicate": { "items": [ "minecraft:water_bucket" ] } } ] } } }, "rewards": { "function": "francium6623:test" }}带注释部分:(在json中不能写入注释,此处使用#作为注释符号用以解释代码的含义。)

{

"criteria": {

"test": { #此项名称在只有一项时无特殊作用。

"trigger": "minecraft:placed_block", #由于我们检查水桶的放置,使用了 placed_block(放置方块)。

"conditions": {

"location": [

{

"condition": "minecraft:reference", #使用谓词文件作为条件检查。

"name": "francium6623:test" #自定义的谓词名称,将会在下文提到。

},

{

"condition": "minecraft:match_tool", #条件检查 match_tool(使用工具)。

"predicate": {

"items": [

"minecraft:water_bucket" #检查目标物品为水桶。

]

}

}

]

}

}

},

"rewards": {

"function": "francium6623:test" #返回函数,将会在下文提到。

}

}

functions 此文件夹内文件格式为.mcfunction。

在functions文件夹下新建test.mcfunction,粘贴以下内容:

advancement revoke @s only francium6623:testfill ~-6 ~-6 ~-6 ~6 ~6 ~6 command_block{auto:1b,Command:"execute align xyz positioned ~0.5 ~ ~0.5 run function francium6623:test2"} replace water[level=0]带注释部分:(mcfunction文件支持在开头使用#使该行变为注释。)

advancement revoke @s only francium6623:test

#剥夺触发函数的进度,使这个进度能重复触发。fill ~-6 ~-6 ~-6 ~6 ~6 ~6 command_block{auto:1b,Command:"execute align xyz positioned ~0.5 ~ ~0.5 run function francium6623:test2"} replace water[level=0]

#fill ~-6 ~-6 ~-6 ~6 ~6 ~6 command_block replace water[level=0]:将玩家附近13x13x13的水源替换为自动执行的命令方块。

#{auto:1b,Command:"命令"}:自动执行内部命令。

#function francium6623:test2:调用函数执行接下来的命令,在下边介绍。

在functions文件夹下新建test2.mcfunction,粘贴以下内容:

execute if predicate francium6623:test run fill ~ ~1 ~ ~ ~1 ~ minecraft:glass replace #francium6623:can_replaceexecute if predicate francium6623:test run setblock ~ ~ ~ minecraft:beaconexecute unless predicate francium6623:test run setblock ~ ~ ~ water

execute if predicate francium6623:test run fill ~ ~1 ~ ~ ~1~ minecraft:glass replace #francium6623:can_replace

#如果满足谓词条件的话把原位置Y+1的位置标签为#francium6623:can_replace内的方块替换为玻璃。

execute if predicate francium6623:test run setblock ~ ~ ~ minecraft:beacon

#如果满足谓词条件的话把原位置替换为信标。

execute unless predicate francium6623:test run setblock ~ ~ ~ water

#如果不满足谓词条件的话把原位置还原为水。

predicates 此文件夹内文件格式为.json。

在predicates文件夹下新建test.json,粘贴以下内容:

[ { "condition": "all_of", "terms": [ { "condition": "minecraft:location_check", "offsetX": -1, "offsetY": 0, "offsetZ": 0, "predicate": { "block": { "blocks": [ "minecraft:cobblestone" ] } } }, { "condition": "minecraft:location_check", "offsetX": 1, "offsetY": 0, "offsetZ": 0, "predicate": { "block": { "blocks": [ "minecraft:cobblestone" ] } } }, { "condition": "minecraft:location_check", "offsetX": 0, "offsetY": 0, "offsetZ": 1, "predicate": { "block": { "blocks": [ "minecraft:cobblestone" ] } } }, { "condition": "minecraft:location_check", "offsetX": 0, "offsetY": 0, "offsetZ": -1, "predicate": { "block": { "blocks": [ "minecraft:cobblestone" ] } } } ] }]带注释部分:(在json中不能写入注释,此处使用#作为注释符号用以解释代码的含义。)

[

{

"condition": "all_of",

"terms": [

{

"condition": "minecraft:location_check", #条件:位置检查,下同

"offsetX": -1,

"offsetY": 0,

"offsetZ": 0,

"predicate": {

"block": {

"blocks": [

"minecraft:cobblestone" #在相对坐标x,y,z的位置为方块:圆石,下同。

]

}

}

},

{

"condition": "minecraft:location_check",

"offsetX": 1,

"offsetY": 0,

"offsetZ": 0,

"predicate": {

"block": {

"blocks": [

"minecraft:cobblestone"

]

}

}

},

{

"condition": "minecraft:location_check",

"offsetX": 0,

"offsetY": 0,

"offsetZ": 1,

"predicate": {

"block": {

"blocks": [

"minecraft:cobblestone"

]

}

}

},

{

"condition": "minecraft:location_check",

"offsetX": 0,

"offsetY": 0,

"offsetZ": -1,

"predicate": {

"block": {

"blocks": [

"minecraft:cobblestone"

]

}

}

}

]

}

]

这样我们就能检测执行位置方块四周是否都为圆石了。

tags 此文件夹内文件格式为.json。

在tags文件夹下新建blocks文件夹,打开后新建can_replace.json,粘贴以下内容:

{ "replace": false, "values": [ "minecraft:cave_air", "minecraft:air" ]}此文件将air和cave_air加入方块标签#francium6623:can_replace。

二:测试

输入/datapack list刷新数据包列表。

在minecraft中输入/datapack enable "file/testdatapack"来启用数据包。

测试发现当周围水上有睡莲时,睡莲会掉落。

当在世界边界或上下界执行操作时,fill指令超出范围。

为什么?怎么办?

对于fill指令超出范围,我们可以缩小fill之后的参数,但是这样会缩小检测范围。

分析我们的实现过程,我们曾将附近的水替换为命令方块用以检测,但是这一步会损坏水面的睡莲。

我们可以把睡莲也替换为命令方块,但是这样可能产生问题,所以选择把睡莲对应位置放置标记实体,在执行前清除为air,执行后还原。

在function文件夹中新建文件marker.mcfunction,将要输入以下内容:由于编辑器卡顿,使用了外部链接marker.mcfunction

kill @e[type=marker,nbt={Tags:["_marker"]}]execute anchored eyes if block ~-6 ~-6 ~-6 minecraft:lily_pad run summon marker ~-6 ~-6 ~-6 {Tags:["_marker"]}execute anchored eyes if block ~-6 ~-6 ~-5 minecraft:lily_pad run summon marker ~-6 ~-6 ~-5 {Tags:["_marker"]}execute anchored eyes if block ~-6 ~-6 ~-4 minecraft:lily_pad run summon marker ~-6 ~-6 ~-4 {Tags:["_marker"]}execute anchored eyes if block ~-6 ~-6 ~-3 minecraft:lily_pad run summon marker ~-6 ~-6 ~-3 {Tags:["_marker"]}............execute anchored eyes if block ~6 ~6 ~3 minecraft:lily_pad run summon marker ~6 ~6 ~3 {Tags:["_marker"]}execute anchored eyes if block ~6 ~6 ~4 minecraft:lily_pad run summon marker ~6 ~6 ~4 {Tags:["_marker"]}execute anchored eyes if block ~6 ~6 ~5 minecraft:lily_pad run summon marker ~6 ~6 ~5 {Tags:["_marker"]}execute anchored eyes if block ~6 ~6 ~6 minecraft:lily_pad run summon marker ~6 ~6 ~6 {Tags:["_marker"]}execute anchored eyes if block ~ ~ ~ minecraft:lily_pad run summon marker ~ ~ ~ {Tags:["_marker"]}

#将当前位置偏移范围-6 -6 -6到6 6 6的位置遍历检测是否为睡莲,如果是则生成具有_marker标签的标记实体。

你也可以使用以下Python代码生成遍历部分:

x=-6y=-6z=-6for x in range(-6,7):for y in range(-6,7):for z in range(-6,7):print ("execute anchored eyes if block ~",x," ~",y," ~",z," minecraft:lily_pad run summon marker ~",x," ~",y," ~",z," {Tags:[\"_marker\"]}",sep="")在此不对Python代码进行解释。

修改test.mcfunction:

advancement revoke @s only francium6623:testfunction francium6623:markerexecute at @e[type=marker,nbt={Tags:["_marker"]}] run setblock ~ ~ ~ airfill ~-6 ~-6 ~-6 ~6 ~6 ~6 command_block{auto:1b,Command:"execute align xyz positioned ~0.5 ~ ~0.5 run function francium6623:test2"} replace water[level=0]schedule function francium6623:test3 2t添加test3.mcfunction:

execute at @e[type=marker,nbt={Tags:["_marker"]}] run setblock ~ ~ ~ lily_padkill @e[type=marker,nbt={Tags:["_marker"]}]function francium6623:marker

#在test中第二行调用marker函数。

execute at @e[type=marker,nbt={Tags:["_marker"]}] run setblock ~ ~ ~ air

#第三行把标记实体位置替换为空气。

schedule function francium6623:test3 2t

#第五行计划函数test3。

execute at @e[type=marker,nbt={Tags:["_marker"]}] run setblock ~ ~ ~ lily_pad

#在test3中第一行还原睡莲,kill @e[type=marker,nbt={Tags:["_marker"]}]

#第二行清除标记。

为什么要使用schedule命令延时2t,我不使用的时候schedule命令延时2t也没有问题?

对于单片睡莲,不使用schedule命令延时2t的确没有问题。

但是当有多片睡莲在一起时,需要延时避免睡莲掉落。

什么原理:不知道能跑就行

三:再次测试

输入/reload重载数据包文件,进行测试,此时睡莲不会再掉落了。

四:打包数据包

打开存档文件夹里的datapacks文件夹,找到testdatapack文件夹。

打开testdatapack文件夹并全选文件,选择7-zip>添加到 "xxxx.zip"。

五:问题

哪些情况不能触发?

使用非水桶放置的水源,你甚至不能使用打破冰获得的水源。

使用命令,修改文件放置的水源。它们不能触发触发器。

使用mod的方块放置器放置的水源。由于它们不能触发触发器,也就不会执行后续操作。

未能实现?

检查:

输入/advancement grant @s only francium6623:test,若提示未知的命令,则为advancements文件夹下的进度文件错误。

输入/function francium6623:xxx,若提示未知的命令,则为functions文件夹下的对应的mcfunction文件错误。

对错误的文件进行修复。

Copyright © 2088 世界杯名额_世界杯结果 - tylzr.com All Rights Reserved.
友情链接