diff --git a/display.lua b/display.lua index e7e5e57..6306724 100644 --- a/display.lua +++ b/display.lua @@ -1,4 +1,11 @@ +-- playername => minetest.pos_to_string(pos1) .. "/" .. minetest.pos_to_string(pos2) +local active_entities = {} + +local function get_entity_key(pos1, pos2) + return minetest.pos_to_string(pos1) .. "/" .. minetest.pos_to_string(pos2) +end + minetest.register_entity("building_lib:display", { initial_properties = { physical = false, @@ -8,19 +15,98 @@ minetest.register_entity("building_lib:display", { visual_size = {x=10, y=10}, textures = {"building_lib_place.png"}, glow = 10 - } + }, + on_step = function(self) + local entry = active_entities[self.playername] + if not entry or entry ~= self.key then + -- not valid anymore + self.object:remove() + end + end }) minetest.register_chatcommand("test", { func = function(name) local player = minetest.get_player_by_name(name) local pos = player:get_pos() - local mapblock_center = mapblock_lib.get_mapblock_center(pos) - - local ent = minetest.add_entity(mapblock_center, "building_lib:display") - ent:set_properties({ - visual_size = {x=5, y=5}, - nametag = "test" - }) + local mapblock_pos = mapblock_lib.get_mapblock(pos) + building_lib.show_preview(name, mapblock_pos, vector.add(mapblock_pos, {x=1, y=1, z=0})) end -}) \ No newline at end of file +}) + +local function add_preview_entity(playername, key, visual_size, pos, rotation) + local ent = minetest.add_entity(pos, "building_lib:display") + local luaent = ent:get_luaentity() + luaent.playername = playername + luaent.key = key + ent:set_properties({ + visual_size = visual_size, + }) + ent:set_rotation(rotation) +end + +function building_lib.has_preview(playername) + return active_entities[playername] +end + +function building_lib.show_preview(playername, mapblock_pos1, mapblock_pos2) + mapblock_pos2 = mapblock_pos2 or mapblock_pos1 + local key = get_entity_key(mapblock_pos1, mapblock_pos2) + if active_entities[playername] == key then + -- already active on the same region + return + end + active_entities[playername] = key + + local min, _ = mapblock_lib.get_mapblock_bounds_from_mapblock(mapblock_pos1) + + local size_mapblocks = vector.subtract(vector.add(mapblock_pos2, 1), mapblock_pos1) -- 1 .. n + local size = vector.multiply(size_mapblocks, 16) -- 16 .. n + local half_size = vector.divide(size, 2) -- 8 .. n + + -- z- + add_preview_entity(playername, key, + {x=size.x, y=size.y}, + vector.add(min, {x=half_size.x-0.5, y=half_size.y-0.5, z=-0.5}), + {x=0, y=0, z=0} + ) + + -- z+ + add_preview_entity(playername, key, + {x=size.x, y=size.y}, + vector.add(min, {x=half_size.x-0.5, y=half_size.y-0.5, z=size.z-0.5}), + {x=0, y=0, z=0} + ) + + -- x- + add_preview_entity(playername, key, + {x=size.z, y=size.y}, + vector.add(min, {x=-0.5, y=half_size.y-0.5, z=half_size.z-0.5}), + {x=0, y=math.pi/2, z=0} + ) + + -- x+ + add_preview_entity(playername, key, + {x=size.z, y=size.y}, + vector.add(min, {x=size.x-0.5, y=half_size.y-0.5, z=half_size.z-0.5}), + {x=0, y=math.pi/2, z=0} + ) + + -- y- + add_preview_entity(playername, key, + {x=size.x, y=size.z}, + vector.add(min, {x=half_size.x-0.5, y=-0.5, z=half_size.z-0.5}), + {x=math.pi/2, y=0, z=0} + ) + + -- y+ + add_preview_entity(playername, key, + {x=size.x, y=size.z}, + vector.add(min, {x=half_size.x-0.5, y=size.y-0.5, z=half_size.z-0.5}), + {x=math.pi/2, y=0, z=0} + ) +end + +function building_lib.clear_preview(playername) + active_entities[playername] = nil +end \ No newline at end of file diff --git a/tools.lua b/tools.lua index cb67dba..de1c092 100644 --- a/tools.lua +++ b/tools.lua @@ -100,4 +100,35 @@ minetest.register_tool("building_lib:remove", { range = 0, on_use = function() end -}) \ No newline at end of file +}) + +-- check for tools +local function pointed_check() + for _, player in ipairs(minetest.get_connected_players()) do + local itemstack = player:get_wielded_item() + local playername = player:get_player_name() + local name = itemstack and itemstack:get_name() + if name == "building_lib:place" then + local pointed_mapblock_pos = mapblock_lib.get_pointed_position(player, 2) + local meta = itemstack:get_meta() + local buildingname = meta:get_string("buildingname") + local building_def = building_lib.buildings[buildingname] + if not building_def then + building_lib.clear_preview(playername) + return + end + local size = building_lib.get_building_size(building_def) + local mapblock_pos2 = vector.add(pointed_mapblock_pos, vector.subtract(size, 1)) + building_lib.show_preview(playername, pointed_mapblock_pos, mapblock_pos2) + + elseif building_lib.has_preview(playername) then + building_lib.clear_preview(playername) + end + end + minetest.after(0, pointed_check) +end + +minetest.after(0, pointed_check) +minetest.register_on_leaveplayer(function(player) + building_lib.clear_preview(player:get_player_name()) +end) \ No newline at end of file