diff --git a/actions/places.lua b/actions/places.lua index d20ccfa..3403914 100644 --- a/actions/places.lua +++ b/actions/places.lua @@ -166,7 +166,9 @@ end function npc.places.add_owned_accessible_place(self, nodes, place_type, walkables) for i = 1, #nodes do -- Check if node has owner - if nodes[i].owner == "" then + local owner = minetest.get_meta(nodes[i].node_pos):get_string("advanced_npc:owner") + --minetest.log("Condition: "..dump(owner == "")) + if owner == "" then -- If node has no owner, check if it is accessible local empty_nodes = npc.places.find_orthogonal_accessible_node( nodes[i].node_pos, nil, 0, true, walkables) @@ -556,6 +558,38 @@ function npc.places.scan_area_for_usable_nodes(pos1, pos2) return result end +-- Helper function to clear metadata in an array of nodes +-- Metadata that will be cleared is: +-- advanced_npc:used +-- advanced_npc:owner +local function clear_metadata(nodes) + local c = 0 + for i = 1, #nodes do + local meta = minetest.get_meta(nodes[i].node_pos) + meta:set_string("advanced_npc:owner", "") + meta:set_string("advanced_npc:used", npc.places.USE_STATE.NOT_USED) + c = c + 1 + end + return c +end + +function npc.places.clear_metadata_usable_nodes_in_area(node_data) + local count = 0 + count = count + clear_metadata(node_data.bed_type) + count = count + clear_metadata(node_data.sittable_type) + count = count + clear_metadata(node_data.furnace_type) + count = count + clear_metadata(node_data.storage_type) + count = count + clear_metadata(node_data.openable_type) + -- Clear workplace nodes + for i = 1, #node_data.workplace_type do + local meta = minetest.get_meta(node_data.workplace_type[i].node_pos) + meta:set_string("work_data", nil) + count = count + 1 + end + return count +end + + -- Specialized function to find doors that are an entrance to a building. -- The definition of an entrance is: -- The openable node with the shortest path to the plotmarker node @@ -579,7 +613,6 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker end end - for i = 1, #openable_nodes do local open_pos = openable_nodes[i].node_pos diff --git a/spawner.lua b/spawner.lua index 9475953..f660eeb 100644 --- a/spawner.lua +++ b/spawner.lua @@ -509,7 +509,7 @@ function npc.spawner.assign_places(self, entrance, node_data, pos) -- Assign beds if #node_data.bed_type > 0 then - -- Assign a specific sittable node to a NPC. + -- Assign a specific bed node to a NPC. npc.places.add_owned_accessible_place(self, node_data.bed_type, npc.places.PLACE_TYPE.BED.PRIMARY) -- Store changes to node_data @@ -1081,6 +1081,10 @@ minetest.register_chatcommand("restore_plotmarkers", { meta:set_int("plot_nr", plot_nr) meta:set_string("infotext", infotext) -- Clear NPC stats, NPC data and node data + -- Clear node_data metadata + local node_data = minetest.deserialize(meta:get_string("node_data")) + npc.places.clear_metadata_usable_nodes_in_area(node_data) + meta:set_string("node_data", nil) meta:set_string("npcs", nil) meta:set_string("npc_stats", nil) @@ -1089,3 +1093,37 @@ minetest.register_chatcommand("restore_plotmarkers", { minetest.chat_send_player(name, "Finished replacement of "..dump(#nodes).." auto-spawners successfully") end }) + +minetest.register_chatcommand("restore_area", { + description = "", + privs = {server = true}, + func = function(name, param) + local args = npc.utils.split(param, " ") + minetest.log("Params: "..dump(args)) + if #args < 2 then + minetest.chat_send_player("Please specify horizontal and vertical radius.") + return + end + local radius = args[1] + local y_adj = args[2] + -- Get player position + local pos = {} + for _,player in pairs(minetest.get_connected_players()) do + if player:get_player_name() == name then + pos = player:get_pos() + break + end + end + -- Search for nodes + -- Calculate positions + local start_pos = {x=pos.x-radius, y=pos.y-y_adj, z=pos.z-radius } + local end_pos = {x=pos.x+radius, y=pos.y+y_adj, z=pos.z+radius } + + -- Scan for usable nodes + local node_data = npc.places.scan_area_for_usable_nodes(start_pos, end_pos) + local removed_count = npc.places.clear_metadata_usable_nodes_in_area(node_data) + + minetest.chat_send_player(name, "Restored "..dump(removed_count).." nodes in area from " + ..minetest.pos_to_string(start_pos).." to "..minetest.pos_to_string(end_pos)) + end +}) diff --git a/utils.lua b/utils.lua index a6bbde0..1a7db52 100644 --- a/utils.lua +++ b/utils.lua @@ -3,6 +3,19 @@ npc.utils = {} +function npc.utils.split(inputstr, sep) + if sep == nil then + sep = "%s" + end + local t={} + local i=1 + for str in string.gmatch(inputstr, "([^"..sep.."]+)") do + t[i] = str + i = i + 1 + end + return t +end + function npc.utils.array_contains(array, item) --minetest.log("Array: "..dump(array)) --minetest.log("Item being searched: "..dump(item))