Teleport cats and tamed wolfs to owner

master
Wuzzy 2017-06-26 22:42:23 +02:00
parent 7e2cbba0a6
commit c73cafdf4a
4 changed files with 69 additions and 0 deletions

63
3_shared.lua Normal file
View File

@ -0,0 +1,63 @@
local pr = PseudoRandom(os.time()*5)
local offsets = {}
for x=-2, 2 do
for z=-2, 2 do
table.insert(offsets, {x=x, y=0, z=z})
end
end
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1.
Larger mobs might have space problems after teleportation.
* dist: Minimum required distance from owner to teleport. Default: 12
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]]
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
return function(self, dtime)
-- No teleportation if no owner or if sitting
if not self.owner or self.order == "sit" then
return
end
if not teleport_check_interval then
teleport_check_interval = 4
end
if not dist then
dist = 12
end
if self._teleport_timer == nil then
self._teleport_timer = teleport_check_interval
return
end
self._teleport_timer = self._teleport_timer - dtime
if self._teleport_timer <= 0 then
self._teleport_timer = teleport_check_interval
local mob_pos = self.object:getpos()
local owner = minetest.get_player_by_name(self.owner)
if not owner then
-- No owner found, no teleportation
return
end
local owner_pos = owner:getpos()
local dist_from_owner = vector.distance(owner_pos, mob_pos)
if dist_from_owner > dist then
-- Check for nodes below air in a 5×1×5 area around the owner position
local check_offsets = table.copy(offsets)
-- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node.
while #check_offsets > 0 do
local r = pr:next(1, #check_offsets)
local telepos = vector.add(owner_pos, check_offsets[r])
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
table.remove(check_offsets, r)
-- Long story short, spawn on a platform
if minetest.registered_nodes[minetest.get_node(telepos).name].walkable == false and
minetest.registered_nodes[minetest.get_node(telepos_below).name].walkable == true then
-- Correct position found! Let's teleport.
self.object:setpos(telepos)
return
end
end
end
end
end
end

View File

@ -48,6 +48,8 @@ else
minetest.register_alias("_:arrow", "throwing:arrow")
mobs:alias_mob("_:arrow_entity", "throwing:arrow_entity")
end
-- Shared functions
dofile(path .. "/3_shared.lua")
--Mob heads
dofile(path .. "/heads.lua") -- maikerumine

View File

@ -101,6 +101,8 @@ cat.order = "roam" -- "sit" or "roam"
cat.owner_loyal = true
cat.tamed = true
cat.runaway = false
-- Automatically teleport cat to owner
cat.do_custom = mobs_mc.make_owner_teleport_function(12)
cat.on_rightclick = function(self, clicker)
if self.child then
return

View File

@ -122,6 +122,8 @@ dog.owner = ""
-- TODO: Start sitting by default
dog.order = "roam"
dog.owner_loyal = true
-- Automatically teleport dog to owner
dog.do_custom = mobs_mc.make_owner_teleport_function(12)
dog.on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item()
if is_flesh(item:get_name()) then