lua
local omega = require("omega")
local print = omega.system.print
print("Hello, world! from example2")
local structures = omega.structures
local blocks = structures.blocks
-- 建筑文件,可以是 schem/schemaic/bdx/mcworld
local source_structure_file = "./空散云雾菜单2.0.bdx"
-- 在临时目录创建一个空建筑
local source_structure_dir = omega.system.temp_dir() -- "./omega_source_structure" -- 临时建筑目录,所谓建筑目录其实就是基岩版存档的文件夹
-- 从建筑文件中读取建筑到临时建筑目录
local source_structure = structures.convert_file_to_structure(source_structure_dir, source_structure_file)
-- 从mc基岩版存档地址(文件夹)中读取建筑
-- local structure = structures.open_or_create_structure("mc基岩版存档地址")
-- 在临时目录创建一个空建筑,如果目录是一个mc基岩版存档,则打开存档
local target_structure_dir = omega.system.temp_dir() -- "./omega_target_structure" -- 输出建筑目录,所谓建筑目录其实就是基岩版存档的文件夹
local target_structure = structures.open_or_create_structure(target_structure_dir)
print(source_structure:get_file_name())
-- source_structure:get_start_pos()
-- source_structure:get_end_pos()
-- source_structure:get_structure_name()
-- source_structure:get_must_block_state()
-- source_structure:gen_mcworld("输出文件名")
-- source_structure:remove()
-- source_structure:set_start_pos(pos)
-- source_structure:set_end_pos(pos)
-- source_structure:set_structure_name(name)
-- source_structure:set_must_block_state(must_block_state)
-- source_structure:apply_alter_to_blocks(start_pos, end_pos, alter_fn, option_ignore_air_block, option_ignore_nbt_block, option_ignore_normal_block)
-- 两个坐标相加
local function add_pos(pos_1, pos_2)
return {
x = pos_1.x + pos_2.x,
y = pos_1.y + pos_2.y,
z = pos_1.z + pos_2.z
}
end
-- 实际的建筑操作代码
local function convert_structure(source_structure, target_structure)
-- 获得源建筑的起始位置和结束位置
local source_start_pos = source_structure:get_start_pos()
local source_end_pos = source_structure:get_end_pos()
-- 将源建筑复制到目标建筑,偏移量(offset)为(0, 0, 0),如果需要移动建筑,可以修改offset
local offset = { x = 0, y = 0, z = 0 }
structures.copy_structure(source_structure, target_structure, source_start_pos, source_end_pos, offset)
-- 本文件中只包含一个建筑,你可以自己搞更花哨的操作
-- 将位置、名称、是否必须使用 block state 等信息从源建筑复制到目标建筑 (因为只有一个建筑)
local target_start_pos = add_pos(source_start_pos, offset)
target_structure:set_start_pos(target_start_pos)
local target_end_pos = add_pos(source_end_pos, offset)
target_structure:set_end_pos(target_end_pos)
target_structure:set_structure_name(source_structure:get_structure_name())
target_structure:set_must_block_state(source_structure:get_must_block_state())
-- 对目标建筑进行修改,在这份文件生成时,命令方块的命令全部被提取出来,放在 key_strings 中
-- 你可以在这里对命令进行修改,然后再写回去
-- 修改的范围
local alter_start_pos = target_start_pos
local alter_end_pos = target_end_pos
-- 忽略范围内的空气方块
local option_ignore_air_block = true
-- 修改范围内的nbt方块
local option_ignore_nbt_block = false
-- 忽略范围内的非nbt方块
local option_ignore_normal_block = true
-- 对于每一个方块,都会调用 alter_fn 函数,该函数返回修改后的方块的 runtime id 和 nbt
local alter_fn = function(x, y, z, block_rtid, nbt)
local nbt_type = nbt:get_id()
-- 只需修改命令块的命令
if nbt_type == "CommandBlock" then
local key_name = nbt:get_string("Command")
-- 将命令块的命令前加一个"#",这样命令块就不会执行命令了,你也可以做其他修改
nbt:set_string("Command", "#" .. key_name)
end
return block_rtid, nbt
end
-- 对目标建筑进行修改
print("开始修改目标建筑, 请稍等...\n")
target_structure:apply_alter_to_blocks(
alter_start_pos, alter_end_pos, -- 范围
alter_fn, -- 修改函数
option_ignore_air_block, option_ignore_nbt_block, option_ignore_normal_block -- 选项
)
return target_structure
end
target_structure = convert_structure(source_structure, target_structure)
source_structure:remove()
local progress_poller = omega.builder.build_structure(
target_structure, -- 需要被导入的建筑
target_structure:get_start_pos(), --被导入的建筑的起始位置
target_structure:get_end_pos(), --被导入建筑的结束位置
{ x = 31000, y = 100, z = 11000 }, --导入到的位置(租赁服中)
2000, -- 导入速度
false, -- 增量构建(false)
false, -- 强制使用block state(false),注:即时这里设置false,如果struceture中use_block_state为true,也会使用block state
false, -- 是否忽略nbt方块(false)
false, --导入时清除目标位置的方块(false)
false, --导入时清理掉落物(false),注: 清理范围为整个租赁服,不止是导入的建筑范围
false, --导入时回退跃点(false)
0 --起始跃点
)
-- 因为一些原因,有时命令块需要导入两次才能保证全部导入,只导入一次可能会漏
local mux_poller = omega.listen.make_mux_poller()
local function on_progress(progress)
print(("progress: %s/%s"):format(progress.total, progress.current))
if progress.total == progress.current then
print("done")
-- 获得输出目录,输出目录为当前目录(.), 这是指程序运行的目录,不是本文件所在的目录
local output_dir = "."
-- 自动计算建议的输出文件名
local output_file_name = (("%s/%s.mcworld"):format(output_dir, target_structure:get_file_name()))
-- 将目标建筑写入到输出文件 (mcworld 格式)
target_structure:gen_mcworld(output_file_name) -- 需要注意,调用这个函数后,建筑就无法再修改/导入/进行其他操作了,因为生成mcworld需要先关闭建筑
-- 当然,你可以再次打开建筑
-- 移除源建筑所在的目录
target_structure:remove()
end
end
mux_poller:poll(progress_poller)
while mux_poller:block_has_next() do
local event = mux_poller:block_get_next()
if event.type == progress_poller then
local progress = event.data
on_progress(progress)
end
end
-- 虽然没有在上面展示,不过这些函数也可以用:
-- nbt 相关
-- local new_nbt = blocks.new_nbt() -- 创建一个空的 nbt
-- print(nbt:is_empty()) -- nbt 是否为空
-- nbt:empty() -- 清空nbt
-- local new_nbt=nbt:copy() -- 复制一个 nbt
-- local str_like_nbt=nbt:to_str() -- 将 nbt 转换为 字符串
-- print(str_like_nbt)
-- nbt=nbt:from_str(str_like_nbt) -- 从 字符串 转换为 nbt
-- rtid 相关
-- print(("air rtid is %s \n"):format(blocks.AIR)) -- 获取空气方块的 runtime id (rtid)
-- local rtid, found = blocks.legacy_block_to_rtid("stained_glass", 1) -- 从名称和数据值获取 rtid\
-- if found then
-- print(("rtid of stained_glass with data value 1 is %s \n"):format(rtid))
-- else
-- print("stained_glass with data value 1 not found\n")
-- end
-- 从 rtid 获取方块的名称和数据值
-- local block_name, data_value, found = blocks.rtid_to_legacy_block(rtid)
-- if found then
-- print(("block name of rtid %s is %s, data value is %s \n"):format(rtid, block_name, data_value))
-- else
-- print(("rtid %s not found\n"):format(rtid))
-- end
-- 从 rtid 获取方块的 java str 名
-- local java_str_name, found = blocks.rtid_to_java_str(rtid)
-- if found then
-- print(("java str name of rtid %s is %s \n"):format(rtid, java_str_name))
-- else
-- print(("rtid %s not found\n"):format(rtid))
-- end
-- 从 java str 名 获取 rtid
-- local rtid, found = blocks.java_str_to_rtid(java_str_name)
-- if found then
-- print(("rtid of java str name %s is %s \n"):format(java_str_name, rtid))
-- else
-- print(("java str name %s not found\n"):format(java_str_name))
-- end1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
贡献者
MrlingXD