Compare commits
7 Commits
d1b9d1c1c1
...
558fc1c04b
Author | SHA1 | Date |
---|---|---|
Starbeamrainbowlabs | 558fc1c04b | |
Starbeamrainbowlabs | 1d53233621 | |
Starbeamrainbowlabs | 66aab7ba64 | |
Starbeamrainbowlabs | fcde8e581c | |
Starbeamrainbowlabs | cfef411bbd | |
Starbeamrainbowlabs | cf8406b80f | |
Starbeamrainbowlabs | e942e4fb2f |
|
@ -7,6 +7,7 @@ Note to self: See the bottom of this file for the release template text.
|
|||
## v1.14: The untitled update (unreleased)
|
||||
- Add `//dome+`, which allows you to change the direction the dome is pointing in, and also create multiple domes at once
|
||||
- Add `//metaball`, which renders 2 or more [metaballs](https://en.wikipedia.org/wiki/Metaballs) in Minetest
|
||||
- Add `//revolve`, which makes multiple evenly-spaced rotated copies of the defined region
|
||||
- Migrate from `depends.txt` to `mod.conf`
|
||||
- `//sculpt`: Fix undefined `default` brush
|
||||
- Commands that modify the terrain now ignore liquids
|
||||
|
@ -15,6 +16,9 @@ Note to self: See the bottom of this file for the release template text.
|
|||
- Add new multi-point selection wand ![A picture of the multi-point wand](https://raw.githubusercontent.com/sbrl/Minetest-WorldEditAdditions/main/worldeditadditions_farwand/textures/worldeditadditions_multiwand.png) to select many points at once. **Not currently compatible with other wands**, as it's a work-in-progress (commands that support/require more than 2 points are hopefully coming soon)
|
||||
- Add `//spline`, for drawing curved lines with an arbitrary number of points **(uses the new multi-point wand)**
|
||||
|
||||
### Bugfixes
|
||||
- Cloud wand: fix typo in item description.
|
||||
|
||||
|
||||
## v1.13: The transformational update (2nd January 2022)
|
||||
- Add [`//sfactor`](https://worldeditadditions.mooncarrot.space/Reference/#sfactor) (_selection factor_) - Selection Tools by @VorTechnix are finished for now.
|
||||
|
|
|
@ -437,6 +437,18 @@ Here are all the above examples together:
|
|||
```
|
||||
|
||||
|
||||
### `//revolve <times> [<pivot_point_number=last_point>]`
|
||||
Makes a given number of copies of the currently defined region (bounded by pos1 and pos2) at a given number of equally spaced points rotated around a given pivot/origin point.
|
||||
|
||||
For example, `//revolve 4` would make rotated copies of the currently defined region at intervals 0° (the source to copy), 90°, 180°, and 270° around the given pivot point.
|
||||
|
||||
`pivot_point_number` is the number of the defined position that should act as the pivot point, or origin for the revolve operation. It defaults to the last position defined. Note that it cannot be pos1 or pos2, as these are used to define the region that should be rotated. Use the [multi-point wand](#multi) to define a position with an index of 3 or more.
|
||||
|
||||
```weacmd
|
||||
//revolve 4
|
||||
//revolve 6 6
|
||||
```
|
||||
|
||||
|
||||
## Terrain
|
||||
<!--
|
||||
|
|
|
@ -31,6 +31,7 @@ dofile(wea.modpath.."/lib/spiral_square.lua")
|
|||
dofile(wea.modpath.."/lib/spiral_circle.lua")
|
||||
dofile(wea.modpath.."/lib/dome.lua")
|
||||
dofile(wea.modpath.."/lib/spline.lua")
|
||||
dofile(wea.modpath.."/lib/revolve.lua")
|
||||
dofile(wea.modpath.."/lib/conv/conv.lua")
|
||||
dofile(wea.modpath.."/lib/erode/erode.lua")
|
||||
dofile(wea.modpath.."/lib/noise/init.lua")
|
||||
|
|
|
@ -16,48 +16,56 @@ local Vector3 = wea_c.Vector3
|
|||
-- @param origin Vector3 The pivot point to rotate around.
|
||||
-- @param times number The number of equally-spaces copies to make.
|
||||
function worldeditadditions.revolve(pos1, pos2, origin, times)
|
||||
local rotation_radians = wea_c.range(0, 1, 1 / times)
|
||||
local rotation_radians = wea_c.table.filter(
|
||||
wea_c.range(0, 1, 1 / times),
|
||||
function (val) return val ~= 0 and val ~= 1 end
|
||||
)
|
||||
|
||||
local pos1_source, pos2_source = Vector3.sort(pos1, pos2)
|
||||
|
||||
-- HACK: with some maths this could be much more efficient.
|
||||
local pos1_target, pos2_target = wea_c.table.unpack(wea_c.table.reduce({
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, math.pi)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, math.pi)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, 0, -math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, 0, -math.pi / 2)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, math.pi, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, math.pi, 0)),
|
||||
Vector3.rotate3d(origin, pos1_source, Vector3.new(0, -math.pi / 2, 0)),
|
||||
Vector3.rotate3d(origin, pos2_source, Vector3.new(0, -math.pi / 2, 0)),
|
||||
}, function(acc, next)
|
||||
return { next:expand_region(acc[1], acc[2]) }
|
||||
end, { pos1_source, pos2_source }))
|
||||
|
||||
|
||||
-- Fetch the nodes in the specified area
|
||||
local manip_source, area_source = worldedit.manip_helpers.init(pos1_source, pos2_source)
|
||||
local data_source = manip:get_data()
|
||||
local data_source = manip_source:get_data()
|
||||
|
||||
local manip_target, area_target = worldedit.manip_helpers.init(pos1_target, pos2_target)
|
||||
local data_target = manip:get_data()
|
||||
local data_target = manip_target:get_data()
|
||||
|
||||
local changed = 0
|
||||
for z = pos2_source.z, pos1_source.z, -1 do
|
||||
for y = pos2_source.y, pos1_source.y, -1 do
|
||||
for x = pos2_source.x, pos1_source.x, -1 do
|
||||
for index, rotation in ipairs(rotation_radians) do
|
||||
local pos_source = Vector3.new(x, y, z)
|
||||
local pos_target = Vector3.rotate3d(
|
||||
origin,
|
||||
pos_source,
|
||||
Vector3.new(0, 0, rotation) -- rotate on Z axis only
|
||||
)
|
||||
|
||||
local i_source = area_source:index(x, y, z)
|
||||
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
|
||||
|
||||
-- TODO: Rotate notes as appropriate
|
||||
data_target[i_target] = data_source[i_source]
|
||||
changed = changed + 1
|
||||
local pos_source = Vector3.new(x, y, z)
|
||||
local i_source = area_source:index(x, y, z)
|
||||
|
||||
-- Lua really sucks sometimes... a continue statement would be v useful here
|
||||
if not wea_c.is_airlike(data_source[i_source]) then
|
||||
for index, rotation in ipairs(rotation_radians) do
|
||||
local pos_target = Vector3.rotate3d(
|
||||
origin,
|
||||
pos_source,
|
||||
-- rotate on Z axis only, convert 0..1 → radians
|
||||
-- TEST on Y axis, 'cause I'm confused
|
||||
Vector3.new(0, rotation * math.pi * 2, 0)
|
||||
):round()
|
||||
|
||||
local i_target = area_target:index(pos_target.x, pos_target.y, pos_target.z)
|
||||
|
||||
-- TODO: Rotate notes as appropriate
|
||||
data_target[i_target] = data_source[i_source]
|
||||
changed = changed + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
local wea_c = worldeditadditions_core
|
||||
local Vector3 = wea_c.Vector3
|
||||
|
||||
|
||||
|
||||
-- ██████ ███████ ██ ██ ██████ ██ ██ ██ ███████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██████ █████ ██ ██ ██ ██ ██ ██ ██ █████
|
||||
-- ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
||||
-- ██ ██ ███████ ████ ██████ ███████ ████ ███████
|
||||
worldeditadditions_core.register_command("revolve", {
|
||||
params = "<times> [<pivot_point_number=last_point>]",
|
||||
description = "Creates a number of copies of the defined region rotated at equal intervals.",
|
||||
privs = { worldedit = true },
|
||||
require_pos = 2,
|
||||
parse = function (params_text)
|
||||
if not params_text then params_text = "" end
|
||||
local parts = wea_c.split_shell(params_text)
|
||||
|
||||
if #parts < 1 then
|
||||
return false, "Error: No number of times specified. times should be a positive integer greater than 1"
|
||||
end
|
||||
|
||||
local times = tonumber(parts[1])
|
||||
local origin = -1 -- -1 = last point
|
||||
|
||||
if not times or times < 2 then
|
||||
return false, "Error: Invalid number of times. The value for times must be a positive integer greater than 1."
|
||||
end
|
||||
|
||||
if #parts > 1 then
|
||||
origin = tonumber(parts[2])
|
||||
if not origin then
|
||||
return false, "Error: Invalid pivot point number. The pivot point number must be a positive integer greater than 2."
|
||||
end
|
||||
if origin == 1 or origin == 2 then
|
||||
return false, "Error: Point numbers 1 and 2 are reserved for defining the region that should be cloned."
|
||||
end
|
||||
end
|
||||
|
||||
return true, times, origin
|
||||
end,
|
||||
nodes_needed = function(name, times)
|
||||
-- TODO: Calculate the bounding box for everything, since we'll be grabbing a VoxelManip for the for entire area and then operating on that
|
||||
return worldedit.volume(worldedit.pos1[name], worldedit.pos2[name]) * times
|
||||
end,
|
||||
func = function(name, times, origin_point_number)
|
||||
local start_time = wea_c.get_ms_time()
|
||||
local pos1, pos2 = Vector3.sort(worldedit.pos1[name], worldedit.pos2[name])
|
||||
|
||||
local pos_count = wea_c.pos.count(name)
|
||||
if pos_count < origin_point_number then
|
||||
return false, "Error: You only have "..pos_count.." points defined, yet requested the origin/pivot point be point "..origin_point_number.."."
|
||||
end
|
||||
|
||||
if origin_point_number == -1 then
|
||||
origin_point_number = pos_count
|
||||
end
|
||||
local origin = wea_c.pos.get(name, origin_point_number)
|
||||
|
||||
local success, changed = worldeditadditions.revolve(
|
||||
pos1, pos2,
|
||||
origin,
|
||||
times
|
||||
)
|
||||
if not success then return success, changed end
|
||||
|
||||
local time_taken = wea_c.get_ms_time() - start_time
|
||||
|
||||
minetest.log("action", name .. " used //revolve at "..pos1.." - "..pos2.." with origin "..origin..", replacing "..changed.." nodes in "..time_taken.."s")
|
||||
return true, changed.." nodes replaced in "..wea_c.format.human_time(time_taken)
|
||||
end
|
||||
})
|
|
@ -37,6 +37,7 @@ dofile(wea_cmd.modpath.."/commands/metaball.lua")
|
|||
dofile(wea_cmd.modpath.."/commands/count.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/sculpt.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/spline.lua")
|
||||
dofile(wea_cmd.modpath.."/commands/revolve.lua")
|
||||
|
||||
-- Meta Commands
|
||||
dofile(wea_cmd.modpath.."/commands/meta/init.lua")
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
local wea = worldeditadditions
|
||||
-- local wea_c = worldeditadditions_core
|
||||
local wea_c = worldeditadditions_core
|
||||
|
||||
minetest.register_tool(":worldeditadditions:cloudwand", {
|
||||
description = "WorldEditAdditions far-reaching additive selectior wand",
|
||||
description = "WorldEditAdditions far-reaching additive selector wand",
|
||||
inventory_image = "worldeditadditions_cloudwand.png",
|
||||
|
||||
on_place = function(itemstack, player, pointed_thing)
|
||||
|
@ -26,6 +26,8 @@ minetest.register_tool(":worldeditadditions:cloudwand", {
|
|||
-- Right click when pointing at nothing
|
||||
-- print("[farwand] on_secondary_use", name)
|
||||
|
||||
-- TODO: Move over to wea_c.pos completely
|
||||
wea.selection.clear_points(name)
|
||||
wea_c.pos.clear(name)
|
||||
end
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue