Places: Add truly owned nodes. NPCs shouldn't override ownership

anymore.
Spawner: Add command "/restore_area" to clear up node ownership & usage in manually spawned places.
"/restore_plotmarkers" now clean up node ownership & usage in mg_villages.
This commit is contained in:
Hector Franqui 2017-10-07 11:28:38 -04:00
parent 8a5e80e2cb
commit d95c8504ec
3 changed files with 87 additions and 3 deletions

View File

@ -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

View File

@ -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
})

View File

@ -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))