mirror of
https://github.com/sbrl/Minetest-WorldEditAdditions.git
synced 2024-12-22 19:45:02 +00:00
Finish farwand implementation
This commit is contained in:
parent
6f20b31763
commit
fbf2b894e5
7 changed files with 196 additions and 20 deletions
|
@ -7,3 +7,9 @@ end
|
|||
function worldeditadditions.vector.lengthsquared(v)
|
||||
return v.x*v.x + v.y*v.y + v.z*v.z
|
||||
end
|
||||
|
||||
function worldeditadditions.vector.floor(v)
|
||||
v.x = math.floor(v.x)
|
||||
v.y = math.floor(v.y)
|
||||
v.z = math.floor(v.z)
|
||||
end
|
||||
|
|
|
@ -65,10 +65,14 @@ end
|
|||
-- @param id number The content/node id to check.
|
||||
-- @return bool Whether the given node/content id is a liquid-ish node or not.
|
||||
function worldeditadditions.is_liquidlike(id)
|
||||
print("[is_liquidlike]")
|
||||
if id == node_id_ignore then return false end
|
||||
if not minetest.registered_nodes[id] then return false end
|
||||
|
||||
local liquidtype = minetest.registered_nodes[id].liquidtype
|
||||
local node_name = minetest.get_name_from_content_id(id)
|
||||
if node_name == nil or not minetest.registered_nodes[node_name] then return false end
|
||||
|
||||
local liquidtype = minetest.registered_nodes[node_name].liquidtype
|
||||
print("[is_liquidlike]", "id", id, "liquidtype", liquidtype)
|
||||
|
||||
if liquidtype == nil or liquidtype == "none" then return false end
|
||||
-- If it's not none, then it has to be a liquid as the only other values are source and flowing
|
||||
|
|
|
@ -14,32 +14,53 @@ function worldeditadditions.raycast(player, maxdist, skip_liquid)
|
|||
local player_pos = player:getpos()
|
||||
player_pos.y = player_pos.y + 1.5 -- Calculate from the eye position
|
||||
|
||||
local divisor = 5
|
||||
for i = 1, maxdist do
|
||||
local j = i / 10
|
||||
local j = i / divisor
|
||||
|
||||
cur_pos.x = (look_dir.x*j) + player_pos.x
|
||||
cur_pos.y = (look_dir.y*j) + player_pos.y
|
||||
cur_pos.z = (look_dir.z*j) + player_pos.z
|
||||
|
||||
local found_node = false
|
||||
|
||||
local node = minetest.get_node_or_nil(cur_pos)
|
||||
if node ~= nil then
|
||||
local node_id = minetest.get_content_id(node.name)
|
||||
local is_air = worldeditadditions.is_airlike(node_id)
|
||||
local node_pos = {
|
||||
x = math.floor(0.5+cur_pos.x),
|
||||
y = math.floor(0.5+cur_pos.y),
|
||||
z = math.floor(0.5+cur_pos.z)
|
||||
}
|
||||
|
||||
-- Don't bother if this is the same position we were looking at before
|
||||
if not (node_pos.x == math.floor(0.5+look_dir.x*(j-divisor))
|
||||
and node_pos.y == math.floor(0.5+look_dir.y*(j-divisor))
|
||||
and node_pos.z == math.floor(0.5+look_dir.z*(j-divisor))) then
|
||||
|
||||
-- ignore = unloaded chunks, as far as I can tell
|
||||
if node_id == node_id_ignore then
|
||||
return nil
|
||||
end
|
||||
local found_node = false
|
||||
|
||||
if is_air == false then
|
||||
if skip_liquid == true then
|
||||
return cur_pos, node_id
|
||||
elseif worldeditadditions.is_liquidlike(node_id) == true then
|
||||
return cur_pos, node_id
|
||||
local node = minetest.get_node_or_nil(node_pos)
|
||||
if node ~= nil then
|
||||
local node_id = minetest.get_content_id(node.name)
|
||||
local is_air = worldeditadditions.is_airlike(node_id)
|
||||
print("[raycast] Scanning "..worldeditadditions.vector.tostring(cur_pos)..", i: "..i..", j: "..j..", found", node.name, "is_air", is_air)
|
||||
|
||||
-- ignore = unloaded chunks, as far as I can tell
|
||||
if node_id == node_id_ignore then
|
||||
print("[raycast] found ignore, returning nil")
|
||||
return nil
|
||||
end
|
||||
|
||||
if is_air == false then
|
||||
if skip_liquid == false then
|
||||
return node_pos, node_id
|
||||
else
|
||||
local is_liquid = worldeditadditions.is_liquidlike(node_id)
|
||||
print("[raycast] is_liquid ", is_liquid)
|
||||
if is_liquid == false then
|
||||
return node_pos, node_id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
worldeditadditions.farwand = {
|
||||
player_data = {}
|
||||
}
|
||||
|
||||
local modpath = minetest.get_modpath("worldeditadditions_farwand")
|
||||
|
||||
dofile(modpath.."/lib/farwand.lua")
|
||||
dofile(modpath.."/lib/chatcommand.lua")
|
||||
dofile(modpath.."/lib/settings.lua")
|
||||
|
|
61
worldeditadditions_farwand/lib/chatcommand.lua
Normal file
61
worldeditadditions_farwand/lib/chatcommand.lua
Normal file
|
@ -0,0 +1,61 @@
|
|||
local farwand = worldeditadditions.farwand -- Convenience shurtcut
|
||||
|
||||
local function parse_params_farwand(params_text)
|
||||
if params_text == nil then
|
||||
return false, "Can't parse nil value"
|
||||
end
|
||||
local parts = worldeditadditions.split(params_text, "%s+", false)
|
||||
|
||||
local key = nil
|
||||
local value = nil
|
||||
|
||||
if #parts >= 1 then
|
||||
key = parts[1]
|
||||
end
|
||||
if #parts >= 2 then
|
||||
value = parts[2]
|
||||
end
|
||||
|
||||
return true, key, value
|
||||
end
|
||||
|
||||
minetest.register_chatcommand("/farwand", {
|
||||
params = "skip_liquid (true|false) | maxdist <number>",
|
||||
description = "Configures your worldeditadditions farwand tool on a per-player basis. skip_liquid configures whether liquids will be skipped when raycasting. maxdist configues the maximum distance to raycast looking for a suitable node (default: 1000, but while higher values mean that it will search further, it's not an exact number of nodes that will be searched)",
|
||||
privs = { worldedit = true },
|
||||
func = function(name, params_text)
|
||||
if name == nil then return end
|
||||
local success, key, value = parse_params_farwand(params_text)
|
||||
print("[/farwand] ", success, key, value)
|
||||
if success == false then
|
||||
worldedit.player_notify(name, key)
|
||||
return
|
||||
end
|
||||
|
||||
if key == "" then
|
||||
worldedit.player_notify(name, "Current settings:\n"
|
||||
.."\tskip_liquid\t"..tostring(farwand.setting_get(name, "skip_liquid")).."\n"
|
||||
.."\tmaxdist\t"..tostring(farwand.setting_get(name, "maxdist")).."\n"
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
if key == "skip_liquid" then
|
||||
local skip_liquid = false
|
||||
if value == "true" then skip_liquid = true end
|
||||
farwand.setting_set(name, "skip_liquid", skip_liquid)
|
||||
worldedit.player_notify(name, "Set skip_liquid to "..tostring(skip_liquid)..".")
|
||||
elseif key == "maxdist" then
|
||||
local maxdist = tonumber(value)
|
||||
if maxdist == nil then
|
||||
worldedit.player_notify(name, "Invalid maxdist '"..value.."' (expected number).")
|
||||
return
|
||||
end
|
||||
farwand.setting_set(name, "maxdist", maxdist)
|
||||
worldedit.player_notify(name, "Set maxdist to "..tostring(maxdist)..".")
|
||||
else
|
||||
worldedit.player_notify(name, "Unknown key '"..key.."' (valid values: skip_liquid, maxdist).")
|
||||
return
|
||||
end
|
||||
end
|
||||
})
|
|
@ -1,20 +1,65 @@
|
|||
local function set_pos1(name, pos)
|
||||
if pos ~= nil then
|
||||
print("[set_pos1]", name, "("..pos.x..", "..pos.y..", "..pos.z..")")
|
||||
worldedit.pos1[name] = pos
|
||||
worldedit.mark_pos1(name)
|
||||
else
|
||||
print("[set_pos1]", name, "nil")
|
||||
end
|
||||
end
|
||||
local function set_pos2(name, pos)
|
||||
if pos ~= nil then
|
||||
print("[set_pos2]", name, "("..pos.x..", "..pos.y..", "..pos.z..")")
|
||||
worldedit.pos2[name] = pos
|
||||
worldedit.mark_pos2(name)
|
||||
else
|
||||
print("[set_pos2]", name, "nil")
|
||||
end
|
||||
end
|
||||
|
||||
local function do_raycast(player)
|
||||
if player == nil then return nil end
|
||||
local player_name = player:get_player_name()
|
||||
|
||||
if worldeditadditions.farwand.player_data[player_name] == nil then
|
||||
worldeditadditions.farwand.player_data[player_name] = { maxdist = 1000, skip_liquid = true }
|
||||
end
|
||||
|
||||
local looking_pos, node_id = worldeditadditions.raycast(
|
||||
player,
|
||||
worldeditadditions.farwand.player_data[player_name].maxdist,
|
||||
worldeditadditions.farwand.player_data[player_name].skip_liquid
|
||||
)
|
||||
return looking_pos, node_id
|
||||
end
|
||||
|
||||
minetest.register_tool(":worldeditadditions:farwand", {
|
||||
description = "WorldEditAdditions far-reaching wand",
|
||||
inventory_image = "worldeditadditions_farwand.png",
|
||||
|
||||
on_place = function(itemstack, player, pointed_thing)
|
||||
print("[farwand] on_place", player:get_player_name())
|
||||
local name = player:get_player_name()
|
||||
print("[farwand] on_place", name)
|
||||
-- Right click when pointing at something
|
||||
-- Pointed thing: https://rubenwardy.com/minetest_modding_book/lua_api.html#pointed_thing
|
||||
local looking_pos, node_id = do_raycast(player)
|
||||
set_pos2(name, looking_pos)
|
||||
end,
|
||||
|
||||
on_use = function(itemstack, player, pointed_thing)
|
||||
print("[farwand] on_use", player:get_player_name())
|
||||
local name = player:get_player_name()
|
||||
print("[farwand] on_use", name)
|
||||
local looking_pos, node_id = do_raycast(player)
|
||||
set_pos1(name, looking_pos)
|
||||
-- Left click when pointing at something or nothing
|
||||
end,
|
||||
|
||||
on_secondary_use = function(itemstack, player, pointed_thing)
|
||||
local name = player:get_player_name()
|
||||
-- Right click when pointing at nothing
|
||||
print("[farwand] on_secondary_use", name)
|
||||
|
||||
print("[farwand] on_secondary_use", player:get_player_name())
|
||||
local looking_pos, node_id = do_raycast(player)
|
||||
set_pos2(name, looking_pos)
|
||||
end
|
||||
})
|
||||
|
|
33
worldeditadditions_farwand/lib/settings.lua
Normal file
33
worldeditadditions_farwand/lib/settings.lua
Normal file
|
@ -0,0 +1,33 @@
|
|||
--- If the settings object for the given player name doesn't exist, it is created.
|
||||
-- @param name The name of the player to ensure has a settings object.
|
||||
local function settings_init(name)
|
||||
if worldeditadditions.farwand.player_data[name] == nil then
|
||||
print("[settings_init] ", worldeditadditions.farwand.player_data)
|
||||
worldeditadditions.farwand.player_data[name] = {
|
||||
maxdist = 1000,
|
||||
skip_liquid = true
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
--- Gets a given farwand setting for the given player name.
|
||||
-- @param string name The name of the player to get the setting for.
|
||||
-- @param string setting_name The name of the setting to fetch.
|
||||
-- @return any The value of the setting.
|
||||
function worldeditadditions.farwand.setting_get(name, setting_name)
|
||||
if setting_name == nil then return nil end
|
||||
settings_init(name)
|
||||
return worldeditadditions.farwand.player_data[name][setting_name]
|
||||
end
|
||||
|
||||
--- Sets a given farwand setting for the given player name to the given value.
|
||||
-- @param string name The name of the player to set the setting for.
|
||||
-- @param string setting_name The name of the setting to set.
|
||||
-- @param any setting_value The value to set the setting to.
|
||||
-- @return bool Whether setting the setting was successful or not.
|
||||
function worldeditadditions.farwand.setting_set(name, setting_name, setting_value)
|
||||
if setting_name == nil then return false end
|
||||
settings_init(name)
|
||||
worldeditadditions.farwand.player_data[name][setting_name] = setting_value
|
||||
return true
|
||||
end
|
Loading…
Reference in a new issue