@@ -192,7 +192,7 @@ worldedit.dome = function(pos, radius, nodename)
192
192
end
193
193
194
194
-- adds a hollow cylinder at `pos` along the `axis` axis ("x" or "y" or "z") with length `length` and radius `radius`, composed of `nodename`, returning the number of nodes added
195
- worldedit .hollow_cylinder = function (pos , axis , length , radius , nodename ) -- wip: rewrite this using voxelmanip
195
+ worldedit .hollow_cylinder = function (pos , axis , length , radius , nodename )
196
196
local other1 , other2
197
197
if axis == " x" then
198
198
other1 , other2 = " y" , " z"
@@ -209,7 +209,7 @@ worldedit.hollow_cylinder = function(pos, axis, length, radius, nodename) --wip:
209
209
currentpos [axis ] = currentpos [axis ] - length
210
210
end
211
211
212
- -- make area stay loaded
212
+ -- set up voxel manipulator
213
213
local manip = minetest .get_voxel_manip ()
214
214
local pos1 = {
215
215
[axis ]= currentpos [axis ],
@@ -221,55 +221,43 @@ worldedit.hollow_cylinder = function(pos, axis, length, radius, nodename) --wip:
221
221
[other1 ]= currentpos [other1 ] + radius ,
222
222
[other2 ]= currentpos [other2 ] + radius
223
223
}
224
- manip :read_from_map (pos1 , pos2 )
224
+ local emerged_pos1 , emerged_pos2 = manip :read_from_map (pos1 , pos2 )
225
+ local area = VoxelArea :new ({MinEdge = emerged_pos1 , MaxEdge = emerged_pos2 })
225
226
226
- -- create schematic for single node column along the axis
227
- local node = {name = nodename , param1 = 255 , param2 = 0 }
227
+ -- fill emerged area with ignore
228
228
local nodes = {}
229
- for i = 1 , length do
230
- nodes [i ] = node
229
+ local ignore = minetest .get_content_id (" ignore" )
230
+ for i = 1 , worldedit .volume (emerged_pos1 , emerged_pos2 ) do
231
+ nodes [i ] = ignore
231
232
end
232
- local schematic = {size = {[axis ]= length , [other1 ]= 1 , [other2 ]= 1 }, data = nodes }
233
233
234
- -- add columns in a circle around axis to form cylinder
235
- local place_schematic = minetest .place_schematic
234
+ -- fill selected area with node
235
+ local node_id = minetest .get_content_id (nodename )
236
+ local min_radius , max_radius = radius * (radius - 1 ), radius * (radius + 1 )
237
+ local stride = {x = 1 , y = area .ystride , z = area .zstride }
238
+ local offset = {x = currentpos .x - emerged_pos1 .x , y = currentpos .y - emerged_pos1 .y , z = currentpos .z - emerged_pos1 .z }
239
+ local min_slice , max_slice = offset [axis ], offset [axis ] + length - 1
236
240
local count = 0
237
- local offset1 , offset2 = 0 , radius
238
- local delta = - radius
239
- while offset1 <= offset2 do
240
- -- add node at each octant
241
- local first1 , first2 = pos [other1 ] + offset1 , pos [other1 ] - offset1
242
- local second1 , second2 = pos [other2 ] + offset2 , pos [other2 ] - offset2
243
- currentpos [other1 ], currentpos [other2 ] = first1 , second1
244
- place_schematic (currentpos , schematic ) -- octant 1
245
- currentpos [other1 ] = first2
246
- place_schematic (currentpos , schematic ) -- octant 4
247
- currentpos [other2 ] = second2
248
- place_schematic (currentpos , schematic ) -- octant 5
249
- currentpos [other1 ] = first1
250
- place_schematic (currentpos , schematic ) -- octant 8
251
- local first1 , first2 = pos [other1 ] + offset2 , pos [other1 ] - offset2
252
- local second1 , second2 = pos [other2 ] + offset1 , pos [other2 ] - offset1
253
- currentpos [other1 ], currentpos [other2 ] = first1 , second1
254
- place_schematic (currentpos , schematic ) -- octant 2
255
- currentpos [other1 ] = first2
256
- place_schematic (currentpos , schematic ) -- octant 3
257
- currentpos [other2 ] = second2
258
- place_schematic (currentpos , schematic ) -- octant 6
259
- currentpos [other1 ] = first1
260
- place_schematic (currentpos , schematic ) -- octant 7
261
-
262
- count = count + 8 -- wip: broken because sometimes currentpos is repeated
263
-
264
- -- move to next location
265
- delta = delta + (offset1 * 2 ) + 1
266
- if delta >= 0 then
267
- offset2 = offset2 - 1
268
- delta = delta - (offset2 * 2 )
241
+ for index2 = - radius , radius do
242
+ local newindex2 = (index2 + offset [other1 ]) * stride [other1 ] + 1 -- offset contributed by other axis 1 plus 1 to make it 1-indexed
243
+ for index3 = - radius , radius do
244
+ local newindex3 = newindex2 + (index3 + offset [other2 ]) * stride [other2 ]
245
+ local squared = index2 * index2 + index3 * index3
246
+ if squared >= min_radius and squared <= max_radius then -- position is on surface of cylinder
247
+ for index1 = min_slice , max_slice do -- add column along axis
248
+ local i = newindex3 + index1 * stride [axis ]
249
+ nodes [i ] = node_id
250
+ end
251
+ count = count + length
252
+ end
269
253
end
270
- offset1 = offset1 + 1
271
254
end
272
- count = count * length -- apply the length to the number of nodes
255
+
256
+ -- update map nodes
257
+ manip :set_data (nodes )
258
+ manip :write_to_map ()
259
+ manip :update_map ()
260
+
273
261
return count
274
262
end
275
263
@@ -324,7 +312,7 @@ worldedit.cylinder = function(pos, axis, length, radius, nodename)
324
312
local newindex2 = (index2 + offset [other1 ]) * stride [other1 ] + 1 -- offset contributed by other axis 1 plus 1 to make it 1-indexed
325
313
for index3 = - radius , radius do
326
314
local newindex3 = newindex2 + (index3 + offset [other2 ]) * stride [other2 ]
327
- if index2 * index2 + index3 * index3 <= max_radius then
315
+ if index2 * index2 + index3 * index3 <= max_radius then -- position is within cylinder
328
316
for index1 = min_slice , max_slice do -- add column along axis
329
317
local i = newindex3 + index1 * stride [axis ]
330
318
nodes [i ] = node_id
0 commit comments