From 853e981992d6acd5276bbcd1ca0201649a6e7f73 Mon Sep 17 00:00:00 2001 From: PilzAdam Date: Sat, 25 May 2013 17:52:09 +0200 Subject: [PATCH] Make sheaps tameable and follow if wheat in hand --- api.lua | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- init.lua | 24 ++++++++++++++++++- 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/api.lua b/api.lua index 24a487b..f218af4 100644 --- a/api.lua +++ b/api.lua @@ -27,6 +27,7 @@ function mobs:register_mob(name, def) shoot_interval = def.shoot_interval, sounds = def.sounds, animation = def.animation, + follow = def.follow, timer = 0, env_damage_timer = 0, -- only if state = "attack" @@ -35,7 +36,7 @@ function mobs:register_mob(name, def) v_start = false, old_y = nil, lifetimer = 600, - + tamed = false, set_velocity = function(self, v) local yaw = self.object:getyaw() @@ -116,7 +117,7 @@ function mobs:register_mob(name, def) end self.lifetimer = self.lifetimer - dtime - if self.lifetimer <= 0 then + if self.lifetimer <= 0 and not tamed then local player_count = 0 for _,obj in ipairs(minetest.env:get_objects_inside_radius(self.object:getpos(), 20)) do if obj:is_player() then @@ -234,6 +235,68 @@ function mobs:register_mob(name, def) end end + if self.follow ~= "" and not self.following then + for _,player in pairs(minetest.get_connected_players()) do + local s = self.object:getpos() + local p = player:getpos() + local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if self.view_range and dist < self.view_range then + self.following = player + end + end + end + + if self.following and self.following:is_player() then + if self.following:get_wielded_item():get_name() ~= self.follow then + self.state = "stand" + self.set_velocity(self, 0) + self.following = nil + self.v_start = false + self:set_animation("stand") + return + end + local s = self.object:getpos() + local p = self.following:getpos() + local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5 + if dist > self.view_range then + self.state = "stand" + self.set_velocity(self, 0) + self.following = nil + self.v_start = false + self:set_animation("stand") + return + end + + local vec = {x=p.x-s.x, y=p.y-s.y, z=p.z-s.z} + local yaw = math.atan(vec.z/vec.x)+math.pi/2 + if self.drawtype == "side" then + yaw = yaw+(math.pi/2) + end + if p.x > s.x then + yaw = yaw+math.pi + end + self.object:setyaw(yaw) + if dist > 2 then + if not self.v_start then + self.v_start = true + self.set_velocity(self, self.walk_velocity) + else + if self.get_velocity(self) <= 0.5 and self.object:getvelocity().y == 0 then + local v = self.object:getvelocity() + v.y = 5 + self.object:setvelocity(v) + end + self.set_velocity(self, self.walk_velocity) + end + self:set_animation("walk") + else + self.v_start = false + self.set_velocity(self, 0) + self:set_animation("stand") + end + return + end + if self.state == "stand" then if math.random(1, 4) == 1 then self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/180*math.pi)) @@ -387,6 +450,9 @@ function mobs:register_mob(name, def) if tmp and tmp.lifetimer then self.lifetimer = tmp.lifetimer - dtime_s end + if tmp and tmp.tamed then + self.tamed = tmp.tamed + end end if self.lifetimer <= 0 then self.object:remove() @@ -396,6 +462,7 @@ function mobs:register_mob(name, def) get_staticdata = function(self) local tmp = { lifetimer = self.lifetimer, + tamed = self.tamed, } return minetest.serialize(tmp) end, diff --git a/init.lua b/init.lua index d1bc16e..e4f4173 100644 --- a/init.lua +++ b/init.lua @@ -186,9 +186,31 @@ mobs:register_mob("mobs:sheep", { walk_start = 81, walk_end = 100, }, + follow = "farming:wheat", + view_range = 5, on_rightclick = function(self, clicker) - if self.naked then + local item = clicker:get_wielded_item() + if item:get_name() == "farming:wheat" then + clicker:set_wielded_item(item) + if not self.tamed then + if not minetest.setting_getbool("creative_mode") then + item:take_item() + end + self.tamed = true + elseif self.naked then + if not minetest.setting_getbool("creative_mode") then + item:take_item() + end + self.food = (self.food or 0) + 1 + if self.food >= 8 then + self.naked = false + self.object:set_properties({ + textures = {"mobs_sheep.png"}, + mesh = "mobs_sheep.x", + }) + end + end return end if clicker:get_inventory() then