• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

BuckarooBanzay / mapblock_lib / 8985509650

07 May 2024 12:40PM UTC coverage: 54.827% (-0.3%) from 55.108%
8985509650

push

github

BuckarooBanzay
add docs for prepared mapblock placement

585 of 1067 relevant lines covered (54.83%)

2715.13 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.45
/serialize_mapblock.lua
1
---------
2
-- mapblock serialization
3

4
local air_content_id = minetest.get_content_id("air")
1✔
5
local ignore_content_id = minetest.get_content_id("ignore")
1✔
6
local placeholder_content_id = nil
1✔
7

8
local has_placeholder_mod = minetest.get_modpath("placeholder")
1✔
9
if has_placeholder_mod then
1✔
10
        placeholder_content_id = minetest.get_content_id("placeholder:placeholder")
2✔
11
end
12

13
-- collect node ids with on_timer attributes
14
local node_ids_with_timer = {}
1✔
15
minetest.register_on_mods_loaded(function()
2✔
16
        for _,node in pairs(minetest.registered_nodes) do
439✔
17
                if node.on_timer then
438✔
18
                        local nodeid = minetest.get_content_id(node.name)
54✔
19
                        node_ids_with_timer[nodeid] = true
54✔
20
                end
21
        end
22
end)
23

24
-- checks if a table is empty
25
local function is_empty(tbl)
26
        return not tbl or not next(tbl)
×
27
end
28

29
-- serialize the mapblock at the given mapblock-position
30
function mapblock_lib.serialize_mapblock(mapblock_pos)
2✔
31
        local manip = minetest.get_voxel_manip()
28✔
32
        local pos1, pos2 = mapblock_lib.get_mapblock_bounds_from_mapblock(mapblock_pos)
28✔
33
        local e1, e2 = manip:read_from_map(pos1, pos2)
28✔
34
        local area = VoxelArea:new({MinEdge=e1, MaxEdge=e2})
28✔
35

36
        local node_data = manip:get_data()
28✔
37
        local param1 = manip:get_light_data()
28✔
38
        local param2 = manip:get_param2_data()
28✔
39

40
        local node_id_map = {}
28✔
41

42
        -- id -> name
43
        local unknown_node_names = {}
28✔
44
        -- name -> id
45
        local unknown_node_ids = {}
28✔
46
        local next_unknown_nodeid = -1
28✔
47

48
        -- prepare data structure
49
        local data = {
28✔
50
                air_only = true,
51
                node_ids = {},
28✔
52
                node_mapping = {},
28✔
53
                param1 = {},
28✔
54
                param2 = {},
28✔
55
                metadata = nil
×
56
        }
57

58
        local timers = {}
28✔
59

60
        -- loop over all blocks and fill cid,param1 and param2
61
        for z=pos1.z,pos2.z do
476✔
62
                for y=pos1.y,pos2.y do
7,616✔
63
                        for x=pos1.x,pos2.x do
121,856✔
64
                                local i = area:index(x,y,z)
114,688✔
65
                                local pos = {x=x, y=y, z=z}
114,688✔
66

67
                                local node_id = node_data[i]
114,688✔
68
                                if node_id == ignore_content_id then
114,688✔
69
                                        -- replace ignore blocks with air
70
                                        node_id = air_content_id
×
71
                                end
72

73
                                if data.air_only and node_id ~= air_content_id then
114,688✔
74
                                        -- mapblock contains not jut air
75
                                        data.air_only = false
28✔
76
                                end
77

78
                                if node_ids_with_timer[node_id] then
114,688✔
79
                                        -- node has a node-timer
80
                                        local timer = minetest.get_node_timer(pos)
×
81
                                        local relative_pos = vector.subtract(pos, pos1)
×
82
                                        if timer:is_started() then
×
83
                                                timers[minetest.pos_to_string(relative_pos)] = {
×
84
                                                        timeout = timer:get_timeout(),
85
                                                        elapsed = math.floor(timer:get_elapsed()) -- truncate decimals
×
86
                                                }
87
                                        end
88
                                end
89

90
                                if has_placeholder_mod and node_id == placeholder_content_id then
114,688✔
91
                                        -- parse placeholder and set original node-data in serialized mapblock
92
                                        local meta = minetest.get_meta(pos)
×
93

94
                                        local original_node = placeholder.unwrap(meta)
×
95

96
                                        -- assign artifical node-id
97
                                        node_id = unknown_node_names[original_node.name]
×
98
                                        if not node_id then
×
99
                                                -- next unknown node-id
100
                                                node_id = next_unknown_nodeid
×
101
                                                next_unknown_nodeid = next_unknown_nodeid - 1
×
102
                                                unknown_node_names[original_node.name] = node_id
×
103
                                                unknown_node_ids[node_id] = original_node.name
×
104
                                        end
105
                                end
106

107
                                table.insert(data.node_ids, node_id)
114,688✔
108
                                table.insert(data.param1, param1[i])
114,688✔
109
                                if node_id == air_content_id then
114,688✔
110
                                        -- fixed param2
111
                                        table.insert(data.param2, 0)
70,030✔
112
                                else
113
                                        -- copy param2
114
                                        table.insert(data.param2, param2[i])
44,658✔
115
                                end
116

117
                                node_id_map[node_id] = true
114,688✔
118
                        end
119
                end
120
        end
121

122
        -- gather node id mapping
123
        for node_id in pairs(node_id_map) do
274✔
124
                local node_name = unknown_node_ids[node_id] or minetest.get_name_from_content_id(node_id)
246✔
125
                data.node_mapping[node_name] = node_id
246✔
126
        end
127

128
        if not data.air_only then
28✔
129
                -- serialize metadata
130
                local pos_with_meta = minetest.find_nodes_with_meta(pos1, pos2)
28✔
131
                for _, mpos in ipairs(pos_with_meta) do
28✔
132
                        local relative_pos = vector.subtract(mpos, pos1)
×
133
                        local i = area:indexp(mpos)
×
134
                        local node_id = node_data[i]
×
135

136
                        if has_placeholder_mod and node_id == placeholder_content_id then
×
137
                                -- placeholder
138
                                local meta = minetest.get_meta(mpos)
×
139
                                local _, metadata = placeholder.unwrap(meta)
×
140

141
                                if not is_empty(metadata.fields) or not is_empty(metadata.inventory) then
×
142
                                        data.metadata = data.metadata or {}
×
143
                                        data.metadata.meta = data.metadata.meta or {}
×
144
                                        data.metadata.meta[minetest.pos_to_string(relative_pos)] = metadata
×
145
                                end
146

147
                        elseif node_id ~= air_content_id then
×
148
                                -- only serialize metadata if the node isn't air
149
                                local meta = minetest.get_meta(mpos):to_table()
×
150

151
                                -- Convert metadata item stacks to item strings
152
                                for _, invlist in pairs(meta.inventory) do
×
153
                                        for index = 1, #invlist do
×
154
                                                local itemstack = invlist[index]
×
155
                                                if itemstack.to_string then
×
156
                                                        invlist[index] = itemstack:to_string()
×
157
                                                end
158
                                        end
159
                                end
160

161
                                -- re-check if metadata actually exists (may happen with minetest.find_nodes_with_meta)
162
                                if not is_empty(meta.fields) or not is_empty(meta.inventory) then
×
163
                                        data.metadata = data.metadata or {}
×
164
                                        data.metadata.meta = data.metadata.meta or {}
×
165
                                        data.metadata.meta[minetest.pos_to_string(relative_pos)] = meta
×
166
                                end
167

168
                                if not is_empty(timers) then
×
169
                                        data.metadata = data.metadata or {}
×
170
                                        data.metadata.timers = timers
×
171
                                end
172
                        end
173
                end
174
        end
175

176
        return data
28✔
177
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc