forked from VoxeLibre/VoxeLibre
Merge pull request 'Villagers will now claim more than red beds. Villagers don't steal players beds.' (#2924) from feature/villagers_pt5 into master
Reviewed-on: MineClone2/MineClone2#2924 Reviewed-by: cora <cora@noreply.git.minetest.land>
This commit is contained in:
commit
99b26f5e3f
|
@ -22,6 +22,19 @@ function table.update_nil(t, ...)
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false)
|
||||||
|
local LOG_MODULE = "[MCL2]"
|
||||||
|
function mcl_util.mcl_log (message, module, bypass_default_logger)
|
||||||
|
local selected_module = LOG_MODULE
|
||||||
|
if module then
|
||||||
|
selected_module = module
|
||||||
|
end
|
||||||
|
if (bypass_default_logger or LOGGING_ON) and message then
|
||||||
|
minetest.log(selected_module .. " " .. message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function mcl_util.file_exists(name)
|
function mcl_util.file_exists(name)
|
||||||
if type(name) ~= "string" then return end
|
if type(name) ~= "string" then return end
|
||||||
local f = io.open(name)
|
local f = io.open(name)
|
||||||
|
|
|
@ -21,11 +21,9 @@ local S = minetest.get_translator("mcl_mobs")
|
||||||
local mob_active_range = tonumber(minetest.settings:get("mcl_mob_active_range")) or 48
|
local mob_active_range = tonumber(minetest.settings:get("mcl_mob_active_range")) or 48
|
||||||
|
|
||||||
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
|
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
|
||||||
|
|
||||||
local LOG_MODULE = "[Mobs]"
|
|
||||||
local function mcl_log (message)
|
local function mcl_log (message)
|
||||||
if LOGGING_ON and message then
|
if LOGGING_ON then
|
||||||
minetest.log(LOG_MODULE .. " " .. message)
|
mcl_util.mcl_log (message, "[Mobs]", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,9 @@ local PATHFINDING = "gowp"
|
||||||
-- will be much easier.
|
-- will be much easier.
|
||||||
|
|
||||||
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
|
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_mobs_villager",false)
|
||||||
local LOG_MODULE = "[Mobs - Villager]"
|
|
||||||
local function mcl_log (message)
|
local function mcl_log (message)
|
||||||
if LOGGING_ON and message then
|
if LOGGING_ON then
|
||||||
minetest.log(LOG_MODULE .. " " .. message)
|
mcl_util.mcl_log (message, "[Mobs - Villager]", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -578,9 +577,6 @@ end
|
||||||
|
|
||||||
jobsites = populate_jobsites()
|
jobsites = populate_jobsites()
|
||||||
|
|
||||||
local spawnable_bed={}
|
|
||||||
table.insert(spawnable_bed, "mcl_beds:bed_red_bottom")
|
|
||||||
|
|
||||||
local function stand_still(self)
|
local function stand_still(self)
|
||||||
self.walk_chance = 0
|
self.walk_chance = 0
|
||||||
self.jump = false
|
self.jump = false
|
||||||
|
@ -648,6 +644,95 @@ function get_activity(tod)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function find_closest_bed (self)
|
||||||
|
local p = self.object:get_pos()
|
||||||
|
|
||||||
|
--local spawnable_bed={}
|
||||||
|
--table.insert(spawnable_bed, "mcl_beds:bed_red_bottom")
|
||||||
|
--local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), spawnable_bed)
|
||||||
|
--if nn then
|
||||||
|
-- mcl_log("Red beds: " .. #nn)
|
||||||
|
--end
|
||||||
|
|
||||||
|
local unclaimed_beds = {}
|
||||||
|
local nn2 = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), {"group:bed"})
|
||||||
|
if nn2 then
|
||||||
|
--mcl_log("All bed parts: " .. #nn2)
|
||||||
|
|
||||||
|
for a,b in pairs(nn2) do
|
||||||
|
mcl_log("b: " .. minetest.pos_to_string(b))
|
||||||
|
|
||||||
|
local bed_node = minetest.get_node(b)
|
||||||
|
local bed_name = bed_node.name
|
||||||
|
local is_bed_bottom = string.find(bed_name,"_bottom")
|
||||||
|
|
||||||
|
local bed_meta = minetest.get_meta(b)
|
||||||
|
local owned_by = bed_meta:get_string("villager")
|
||||||
|
--mcl_log("Owned by villager: ".. tostring(owned_by))
|
||||||
|
|
||||||
|
if (owned_by and owned_by == self._id) then
|
||||||
|
mcl_log("Clear as already owned by me.")
|
||||||
|
bed_meta:set_string("villager", nil)
|
||||||
|
owned_by = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if is_bed_bottom then
|
||||||
|
local bed_top = mcl_beds.get_bed_top (b)
|
||||||
|
mcl_log("bed_top: " .. tostring(bed_top))
|
||||||
|
|
||||||
|
local bed_top_node = minetest.get_node(bed_top)
|
||||||
|
if bed_top_node then
|
||||||
|
mcl_log("There is a block here for bed top: ".. bed_top_node.name)
|
||||||
|
else
|
||||||
|
mcl_log("There is no block here for bed top")
|
||||||
|
end
|
||||||
|
|
||||||
|
local bed_top_meta = minetest.get_meta(bed_top)
|
||||||
|
local owned_by_player = bed_top_meta:get_string("player")
|
||||||
|
if bed_top_meta then
|
||||||
|
mcl_log("Player: " .. tostring(owned_by_player))
|
||||||
|
else
|
||||||
|
mcl_log("No bed top meta")
|
||||||
|
end
|
||||||
|
|
||||||
|
if owned_by == "" and (not owned_by_player or owned_by_player == "") then
|
||||||
|
table.insert(unclaimed_beds, b)
|
||||||
|
mcl_log("is an unowned bed bottom")
|
||||||
|
else
|
||||||
|
|
||||||
|
end
|
||||||
|
else
|
||||||
|
--mcl_log("bed_node name: " .. bed_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local distance_to_closest_block = nil
|
||||||
|
local closest_block = nil
|
||||||
|
|
||||||
|
if unclaimed_beds then
|
||||||
|
mcl_log("All unclaimed bed bottoms: " .. #unclaimed_beds)
|
||||||
|
|
||||||
|
for i,b in pairs(unclaimed_beds) do
|
||||||
|
mcl_log("b: " .. minetest.pos_to_string(b))
|
||||||
|
local distance_to_block = vector.distance(p, b)
|
||||||
|
mcl_log("Distance to block ".. i .. ": ".. distance_to_block)
|
||||||
|
|
||||||
|
if not distance_to_closest_block or distance_to_closest_block > distance_to_block then
|
||||||
|
mcl_log("This block is closer than the last.")
|
||||||
|
closest_block = b
|
||||||
|
distance_to_closest_block = distance_to_block
|
||||||
|
end
|
||||||
|
|
||||||
|
local bed_node = minetest.get_node(b)
|
||||||
|
local bed_name = bed_node.name
|
||||||
|
mcl_log("bed_node name: " .. bed_name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return closest_block
|
||||||
|
end
|
||||||
|
|
||||||
local function find_closest_unclaimed_block (p, requested_block_types)
|
local function find_closest_unclaimed_block (p, requested_block_types)
|
||||||
local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), requested_block_types)
|
local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48), requested_block_types)
|
||||||
|
|
||||||
|
@ -681,7 +766,10 @@ local function check_bed (entity)
|
||||||
end
|
end
|
||||||
|
|
||||||
local n = minetest.get_node(b)
|
local n = minetest.get_node(b)
|
||||||
if n and n.name ~= "mcl_beds:bed_red_bottom" then
|
|
||||||
|
local is_bed_bottom = string.find(n.name,"_bottom")
|
||||||
|
mcl_log("" .. tostring(is_bed_bottom))
|
||||||
|
if n and not is_bed_bottom then
|
||||||
mcl_log("Where did my bed go?!")
|
mcl_log("Where did my bed go?!")
|
||||||
entity._bed = nil --the stormtroopers have killed uncle owen
|
entity._bed = nil --the stormtroopers have killed uncle owen
|
||||||
return false
|
return false
|
||||||
|
@ -749,28 +837,44 @@ local function take_bed (entity)
|
||||||
|
|
||||||
local p = entity.object:get_pos()
|
local p = entity.object:get_pos()
|
||||||
|
|
||||||
local closest_block = find_closest_unclaimed_block (p, spawnable_bed)
|
local closest_block = find_closest_bed (entity)
|
||||||
|
|
||||||
if closest_block then
|
if closest_block then
|
||||||
local m = minetest.get_meta(closest_block)
|
|
||||||
mcl_log("Can we path to bed: "..minetest.pos_to_string(closest_block) )
|
mcl_log("Can we path to bed: "..minetest.pos_to_string(closest_block) )
|
||||||
local gp = mcl_mobs:gopath(entity, closest_block,function(self)
|
local distance_to_block = vector.distance(p, closest_block)
|
||||||
if self then
|
mcl_log("Distance: " .. distance_to_block)
|
||||||
self.order = SLEEP
|
|
||||||
mcl_log("Sleepy time" )
|
|
||||||
else
|
|
||||||
mcl_log("Can't sleep, no self in the callback" )
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
if gp then
|
|
||||||
mcl_log("Nice bed. I'll defintely take it as I can path")
|
|
||||||
m:set_string("villager", entity._id)
|
|
||||||
entity._bed = closest_block
|
|
||||||
else
|
|
||||||
mcl_log("Awww. I can't find my bed.")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
if distance_to_block < 2 then
|
||||||
|
local m = minetest.get_meta(closest_block)
|
||||||
|
local owner = m:get_string("villager")
|
||||||
|
mcl_log("owner: ".. owner)
|
||||||
|
if owner and owner ~= "" and owner ~= entity._id then
|
||||||
|
mcl_log("Already taken")
|
||||||
|
if entity.order == "stand" then entity.order = nil end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if entity.order ~= SLEEP then
|
||||||
|
mcl_log("Sleepy time" )
|
||||||
|
entity.order = SLEEP
|
||||||
|
m:set_string("villager", entity._id)
|
||||||
|
entity._bed = closest_block
|
||||||
|
else
|
||||||
|
--entity.order = nil
|
||||||
|
mcl_log("Set as sleep already..." )
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local gp = mcl_mobs:gopath(entity, closest_block,function(self) end)
|
||||||
|
if gp then
|
||||||
|
mcl_log("Nice bed. I'll defintely take it as I can path")
|
||||||
|
else
|
||||||
|
mcl_log("Awww. I can't find my bed.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
mcl_log("Cannot find a bed to claim.")
|
||||||
|
if entity.order == "stand" then entity.order = nil end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function has_golem(pos)
|
local function has_golem(pos)
|
||||||
|
@ -1105,11 +1209,46 @@ local function go_to_town_bell(self)
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function validate_bed(self)
|
||||||
|
if not self or not self._bed then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local n = mcl_vars.get_node(self._bed)
|
||||||
|
if not n then
|
||||||
|
self._bed = nil
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local bed_valid = true
|
||||||
|
|
||||||
|
local m = minetest.get_meta(self._bed)
|
||||||
|
local owned_by_player = m:get_string("player")
|
||||||
|
mcl_log("Player owner: " .. owned_by_player)
|
||||||
|
if owned_by_player ~= "" then
|
||||||
|
mcl_log("Player owns this. Villager won't take this.")
|
||||||
|
m:set_string("villager", nil)
|
||||||
|
self._bed = nil
|
||||||
|
bed_valid = false
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if m:get_string("villager") ~= self._id then
|
||||||
|
mcl_log("This bed is owned by another player. I'll unclaim.")
|
||||||
|
self._bed = nil
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
mcl_log("Bed is valid")
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
local function do_activity (self)
|
local function do_activity (self)
|
||||||
-- Maybe just check we're pathfinding first?
|
-- Maybe just check we're pathfinding first?
|
||||||
|
|
||||||
if not self._bed and self.state ~= PATHFINDING then
|
if not validate_bed(self) and self.state ~= PATHFINDING then
|
||||||
--mcl_log("Villager has no bed. Currently at location: "..minetest.pos_to_string(self.object:get_pos()))
|
if self.order == SLEEP then self.order = nil end
|
||||||
|
mcl_log("Villager has no bed. Currently at location: "..minetest.pos_to_string(self.object:get_pos()))
|
||||||
take_bed (self)
|
take_bed (self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1879,7 +2018,7 @@ mcl_mobs:register_mob("mobs_mc:villager", {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if has_player then
|
if has_player then
|
||||||
minetest.log("verbose", "[mobs_mc] Player near villager found!")
|
--minetest.log("verbose", "[mobs_mc] Player near villager found!")
|
||||||
stand_still(self)
|
stand_still(self)
|
||||||
else
|
else
|
||||||
--minetest.log("verbose", "[mobs_mc] No player near villager found!")
|
--minetest.log("verbose", "[mobs_mc] No player near villager found!")
|
||||||
|
|
|
@ -10,6 +10,10 @@ local explosions_mod = minetest.get_modpath("mcl_explosions")
|
||||||
local spawn_mod = minetest.get_modpath("mcl_spawn")
|
local spawn_mod = minetest.get_modpath("mcl_spawn")
|
||||||
local worlds_mod = minetest.get_modpath("mcl_worlds")
|
local worlds_mod = minetest.get_modpath("mcl_worlds")
|
||||||
|
|
||||||
|
local function mcl_log (message)
|
||||||
|
mcl_util.mcl_log (message, "[Beds]")
|
||||||
|
end
|
||||||
|
|
||||||
-- Helper functions
|
-- Helper functions
|
||||||
|
|
||||||
local function get_look_yaw(pos)
|
local function get_look_yaw(pos)
|
||||||
|
@ -300,6 +304,37 @@ function mcl_beds.skip_night()
|
||||||
minetest.set_timeofday(0.25) -- tod = 6000
|
minetest.set_timeofday(0.25) -- tod = 6000
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mcl_beds.get_bed_top (pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
|
local bed_top_pos = vector.add(pos, dir)
|
||||||
|
local bed_top = minetest.get_node(bed_top_pos)
|
||||||
|
|
||||||
|
if bed_top then
|
||||||
|
mcl_log("Has a bed top")
|
||||||
|
else
|
||||||
|
mcl_log("No bed top")
|
||||||
|
end
|
||||||
|
return bed_top_pos
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_beds.get_bed_bottom (pos)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
local dir = minetest.facedir_to_dir(node.param2)
|
||||||
|
mcl_log("Dir: " .. tostring(dir))
|
||||||
|
local bed_bottom = vector.add(pos, -dir)
|
||||||
|
mcl_log("bed_bottom: " .. tostring(bed_bottom))
|
||||||
|
|
||||||
|
local bed_bottom_node = minetest.get_node(bed_bottom)
|
||||||
|
if bed_bottom_node then
|
||||||
|
mcl_log("Bed bottom node name:" .. bed_bottom_node.name)
|
||||||
|
else
|
||||||
|
mcl_log("Didn't get bed bottom")
|
||||||
|
end
|
||||||
|
|
||||||
|
return bed_bottom
|
||||||
|
end
|
||||||
|
|
||||||
function mcl_beds.on_rightclick(pos, player, is_top)
|
function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
-- Anti-Inception: Don't allow to sleep while you're sleeping
|
-- Anti-Inception: Don't allow to sleep while you're sleeping
|
||||||
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
|
if player:get_meta():get_string("mcl_beds:sleeping") == "true" then
|
||||||
|
@ -329,9 +364,7 @@ function mcl_beds.on_rightclick(pos, player, is_top)
|
||||||
if is_top then
|
if is_top then
|
||||||
message = select(2, lay_down(player, ppos, pos))
|
message = select(2, lay_down(player, ppos, pos))
|
||||||
else
|
else
|
||||||
local node = minetest.get_node(pos)
|
local other = mcl_beds.get_bed_top (pos)
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
|
||||||
local other = vector.add(pos, dir)
|
|
||||||
message = select(2, lay_down(player, ppos, other))
|
message = select(2, lay_down(player, ppos, other))
|
||||||
end
|
end
|
||||||
if message then
|
if message then
|
||||||
|
|
|
@ -4,6 +4,10 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
local mg_name = minetest.get_mapgen_setting("mg_name")
|
local mg_name = minetest.get_mapgen_setting("mg_name")
|
||||||
local storage = minetest.get_mod_storage()
|
local storage = minetest.get_mod_storage()
|
||||||
|
|
||||||
|
local function mcl_log (message)
|
||||||
|
mcl_util.mcl_log (message, "[Spawn]")
|
||||||
|
end
|
||||||
|
|
||||||
-- Parameters
|
-- Parameters
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
@ -429,6 +433,41 @@ function mcl_spawn.set_spawn_pos(player, pos, message)
|
||||||
else
|
else
|
||||||
local oldpos = minetest.string_to_pos(meta:get_string("mcl_beds:spawn"))
|
local oldpos = minetest.string_to_pos(meta:get_string("mcl_beds:spawn"))
|
||||||
meta:set_string("mcl_beds:spawn", minetest.pos_to_string(pos))
|
meta:set_string("mcl_beds:spawn", minetest.pos_to_string(pos))
|
||||||
|
|
||||||
|
-- Set player ownership on bed
|
||||||
|
local bed_node = minetest.get_node(pos)
|
||||||
|
local bed_meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
local bed_bottom = mcl_beds.get_bed_bottom (pos)
|
||||||
|
local bed_bottom_meta = minetest.get_meta(bed_bottom)
|
||||||
|
|
||||||
|
if bed_meta then
|
||||||
|
if bed_node then
|
||||||
|
mcl_log("Bed name: " .. bed_node.name)
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_log("Setting bed meta: " .. player:get_player_name())
|
||||||
|
bed_meta:set_string("player", player:get_player_name())
|
||||||
|
|
||||||
|
-- Pass in villager as arg. Shouldn't know about villagers
|
||||||
|
if bed_bottom_meta then
|
||||||
|
mcl_log("Removing villager from bed bottom meta")
|
||||||
|
bed_bottom_meta:set_string("villager", nil)
|
||||||
|
else
|
||||||
|
mcl_log("Cannot remove villager from bed bottom meta")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local old_bed_meta = minetest.get_meta(oldpos)
|
||||||
|
if oldpos ~= pos and old_bed_meta then
|
||||||
|
mcl_log("Removing old bed meta")
|
||||||
|
old_bed_meta:set_string("player", "")
|
||||||
|
else
|
||||||
|
mcl_log("No old bed meta to remove or same as current")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if oldpos then
|
if oldpos then
|
||||||
-- We don't bother sending a message if the new spawn pos is basically the same
|
-- We don't bother sending a message if the new spawn pos is basically the same
|
||||||
spawn_changed = vector.distance(pos, oldpos) > 0.1
|
spawn_changed = vector.distance(pos, oldpos) > 0.1
|
||||||
|
|
Loading…
Reference in New Issue