add snapping to grid
This commit is contained in:
parent
6020a94ccf
commit
170d35b90d
1
init.lua
1
init.lua
@ -26,6 +26,7 @@ dofile(MP .. "/craft.lua")
|
||||
dofile(MP .. "/record.lua")
|
||||
dofile(MP .. "/playback.lua")
|
||||
dofile(MP .. "/registry.lua")
|
||||
dofile(MP .. "/snap.lua")
|
||||
|
||||
if minetest.get_modpath("mtt") and mtt.enabled then
|
||||
dofile(MP .. "/configure.spec.lua")
|
||||
|
@ -3,19 +3,6 @@ local FORMSPEC_NAME = "pick_and_place:place"
|
||||
local has_mapsync = minetest.get_modpath("mapsync")
|
||||
local has_blockexchange = minetest.get_modpath("blockexchange")
|
||||
|
||||
local function get_pos(meta, player)
|
||||
local size = minetest.string_to_pos(meta:get_string("size"))
|
||||
local distance = vector.distance(vector.new(), size)
|
||||
local radius = math.ceil(distance / 2)
|
||||
local offset = vector.round(vector.divide(size, 2))
|
||||
|
||||
local pos1 = pick_and_place.get_pointed_position(player, radius + 2)
|
||||
pos1 = vector.subtract(pos1, offset)
|
||||
local pos2 = vector.add(pos1, vector.subtract(size, 1))
|
||||
|
||||
return pos1, pos2
|
||||
end
|
||||
|
||||
-- notify supported mods of changes
|
||||
local function notify_change(pos1, pos2)
|
||||
if has_blockexchange then
|
||||
@ -39,7 +26,8 @@ minetest.register_tool("pick_and_place:place", {
|
||||
local controls = player:get_player_control()
|
||||
|
||||
local meta = itemstack:get_meta()
|
||||
local pos1, pos2 = get_pos(meta, player)
|
||||
local size = minetest.string_to_pos(meta:get_string("size"))
|
||||
local pos1, pos2 = pick_and_place.get_placement_pos(size, player)
|
||||
|
||||
if controls.aux1 then
|
||||
-- removal
|
||||
@ -85,7 +73,8 @@ minetest.register_tool("pick_and_place:place", {
|
||||
local controls = player:get_player_control()
|
||||
|
||||
local meta = itemstack:get_meta()
|
||||
local pos1, pos2 = get_pos(meta, player)
|
||||
local size = minetest.string_to_pos(meta:get_string("size"))
|
||||
local pos1, pos2 = pick_and_place.get_placement_pos(size, player)
|
||||
|
||||
if controls.aux1 then
|
||||
-- removal preview
|
||||
|
81
snap.lua
Normal file
81
snap.lua
Normal file
@ -0,0 +1,81 @@
|
||||
|
||||
-- playername -> pos
|
||||
local origin_map = {}
|
||||
|
||||
-- playername -> size
|
||||
local size_map = {}
|
||||
-- TODO: persistence per player (load on join, save on set)
|
||||
|
||||
local function snap_axis(axis, origin, size, pos)
|
||||
local half_size = math.ceil(size[axis] / 2)
|
||||
|
||||
-- delta from origin
|
||||
local diff = pos[axis] - origin[axis]
|
||||
local o = diff % size[axis]
|
||||
if o >= half_size then
|
||||
-- round up
|
||||
pos[axis] = pos[axis] + (size[axis] - o)
|
||||
elseif o > 0 then
|
||||
-- round down
|
||||
pos[axis] = pos[axis] - o
|
||||
end
|
||||
end
|
||||
|
||||
function pick_and_place.get_placement_pos(size, player)
|
||||
local distance = vector.distance(vector.new(), size)
|
||||
local radius = math.ceil(distance / 2)
|
||||
local offset = vector.round(vector.divide(size, 2))
|
||||
local playername = player:get_player_name()
|
||||
|
||||
local pos1 = pick_and_place.get_pointed_position(player, radius + 2)
|
||||
pos1 = vector.subtract(pos1, offset)
|
||||
|
||||
local origin = origin_map[playername]
|
||||
local snap_size = size_map[playername]
|
||||
if origin and snap_size then
|
||||
-- apply grid-snapping
|
||||
snap_axis("x", origin, size, pos1)
|
||||
snap_axis("y", origin, size, pos1)
|
||||
snap_axis("z", origin, size, pos1)
|
||||
end
|
||||
|
||||
local pos2 = vector.add(pos1, vector.subtract(size, 1))
|
||||
return pos1, pos2
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("pnp_snap", {
|
||||
params = "[on|off]",
|
||||
description = "enable or disable grid snapping with the current placement tool dimensions and origin",
|
||||
func = function(name, param)
|
||||
if param == "on" then
|
||||
-- enable grid
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if not player then
|
||||
return false, "player not found"
|
||||
end
|
||||
local itemstack = player:get_wielded_item()
|
||||
if itemstack:get_name() ~= "pick_and_place:place" then
|
||||
return false, "no placement tool selected"
|
||||
end
|
||||
|
||||
local meta = itemstack:get_meta()
|
||||
local size = minetest.string_to_pos(meta:get_string("size"))
|
||||
local pos1 = pick_and_place.get_placement_pos(size, player)
|
||||
|
||||
origin_map[name] = pos1
|
||||
size_map[name] = size
|
||||
|
||||
elseif param == "off" then
|
||||
-- disable grid
|
||||
origin_map[name] = nil
|
||||
size_map[name] = nil
|
||||
end
|
||||
|
||||
if origin_map[name] then
|
||||
return true, "grid set with origin: " .. minetest.pos_to_string(origin_map[name]) ..
|
||||
" and size: " .. minetest.pos_to_string(size_map[name])
|
||||
else
|
||||
return true, "grid disabled"
|
||||
end
|
||||
end
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user