diff --git a/init.lua b/init.lua index c27944a..5e43541 100644 --- a/init.lua +++ b/init.lua @@ -1,5 +1,11 @@ local player_waypoints = {} local update_interval = 1.31415 +local compass_precision = 10 -- set to 1 to show whole number or 10 for 1 decimal +local waypoint_color = 0xFC7D0A +local target_above = false +local point_to_objects = false -- unimplemented +local point_to_liquids = true +local compass_range = 96 -- lua metatables? what is that? :P -- local function get_compass_meta_id(meta) @@ -18,33 +24,16 @@ local function set_compass_meta_label(meta, label) end -local function pos_serialize(pos) - -- strip "(" and ")" - return string.sub(minetest.pos_to_string(pos), 2, -2) -end - - -local function pos_deserialize(str) - -- numbers are separated by "," - local tmp = {} - for n in string.gmatch(str, "([^,]+)") do - table.insert(tmp, n) - end - tmp[1] = tonumber(tmp[1]) or 0 - tmp[2] = tonumber(tmp[2]) or 0 - tmp[3] = tonumber(tmp[3]) or 0 - return {x = tmp[1], y = tmp[2], z = tmp[3]} -end local function set_compass_meta_pos(meta, pos) - local pos_str = pos_serialize(pos) + local pos_str = minetest.serialize(pos) meta:set_string("waypoint_compass:position", pos_str) end local function get_compass_meta_pos(meta) - return pos_deserialize(meta:get_string("waypoint_compass:position")) + return minetest.deserialize(meta:get_string("waypoint_compass:position")) end -- local function set_compass_meta_pos(meta, pos) @@ -57,23 +46,55 @@ end -- return minetest.get_position_from_hash(meta:get_int("waypoint_compass:position")) -- end -minetest.register_tool("waypoint_compass:compass", { - description = "Waypoint compass", - short_description = "Waypoint compass", - inventory_image = "Waypoint_compass_inventory_image.png", - wield_scale = {x = 0.5, y = 0.5, z = 0.5}, - range = 160, -- TODO what's the good range? - on_place = function(itemstack, placer, pointed_thing) - if pointed_thing and pointed_thing.type == "node" then - local pointed_pos = pointed_thing.above - local meta = itemstack:get_meta() - meta:set_string("description", string.format("Waypoint compass %s", minetest.pos_to_string(pointed_pos))) - set_compass_meta_pos(meta, pointed_pos) - --set_compass_meta_label(meta, minetest.pos_to_string(pointed_pos)) - --print("meta pos", minetest.pos_to_string(get_compass_meta_pos(meta))) - return itemstack - end - end, +local function set_waypoint_at_pointed_place(itemstack, user, pointed_thing) + if pointed_thing and pointed_thing.type == "node" then + local pointed_pos = target_above and pointed_thing.above or pointed_thing.under + local meta = itemstack:get_meta() + meta:set_string("description", string.format("Waypoint compass %s", minetest.pos_to_string(pointed_pos))) + set_compass_meta_pos(meta, pointed_pos) + set_compass_meta_label(meta, minetest.pos_to_string(pointed_pos)) + return itemstack + end + -- TODO handle entities? +end + + +-- return first thing player is pointing at +local function raycast_crosshair(player, range) + local p_pos = player:get_pos() + local p_eye_height = player:get_properties().eye_height + local p_eye_pos = { x = p_pos.x, y = p_pos.y + p_eye_height, z = p_pos.z } + local to = vector.add(p_eye_pos, vector.multiply(player:get_look_dir(), range)) + local ray = minetest.raycast(p_eye_pos, to, point_to_objects, point_to_liquids) + local pointed_thing = ray:next() + return pointed_thing + -- while pointed_thing do + -- print(pointed_thing.type, minetest.pos_to_string(pointed_thing.under)) + -- pointed_thing = ray:next() + -- end +end + + +minetest.register_tool( + "waypoint_compass:compass", { + description = "Waypoint compass", + short_description = "Waypoint compass", + inventory_image = "Waypoint_compass_inventory_image.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + range = 2.0, -- TODO what's the good range? + on_place = function(itemstack, placer, pointed_thing) + set_waypoint_at_pointed_place(itemstack, placer, pointed_thing) + return itemstack + end, + on_secondary_use = function(itemstack, user, pointed_thing) + if pointed_thing.type == "nothing" then + if user:is_player() then + pointed_thing = raycast_crosshair(user, compass_range) + end + end + set_waypoint_at_pointed_place(itemstack, user, pointed_thing) + return itemstack + end, }) @@ -93,8 +114,8 @@ local function show_hud_waypoint(player, compass_item_meta) hud_elem_type = "waypoint", name = waypoint_name, text = "m", - precision=1, - number = 0xFC7D0A, + precision= compass_precision, + number = waypoint_color, world_pos = get_compass_meta_pos(compass_item_meta), }) -- store HUD elemnt id to remove it later @@ -120,7 +141,7 @@ minetest.register_globalstep(function(dtime) local waypoint_pos = get_compass_meta_pos(meta) -- remove different waypoint if it exists if player_waypoints[player_name] and - (pos_serialize(player_waypoints[player_name].pos) ~= pos_serialize(waypoint_pos)) then + (player_waypoints[player_name].pos ~= waypoint_pos) then remove_hud_waypoint(player, player_name) end -- show new waypoint