From 933543529bd3f4e9847e85d755609e794fc0f48f Mon Sep 17 00:00:00 2001 From: LeMagnesium Date: Wed, 4 Nov 2015 16:29:28 +0100 Subject: [PATCH] [mobs] Update (tidy code) - Put back calc_velocity - Update mobs mod - Change the way chicken drop eggs (use throwing-like entities) --- mods/mobs/README.txt | 1 + mods/mobs/api.lua | 203 +++++++++++++++++++++++++++++++++++------- mods/mobs/chicken.lua | 119 +++++++++++++++++++++++-- mods/mobs/sheep.lua | 17 +--- 4 files changed, 285 insertions(+), 55 deletions(-) diff --git a/mods/mobs/README.txt b/mods/mobs/README.txt index 7e6d28b0..43fb832f 100755 --- a/mods/mobs/README.txt +++ b/mods/mobs/README.txt @@ -28,6 +28,7 @@ This mod contains the following additions: Changelog: +1.19- Chickens now drop egg items instead of placing the egg, also throwing eggs result in 1/8 chance of spawning chick 1.18- Added docile_by_day flag so that monsters will not attack automatically during daylight hours unless hit first 1.17- Added 'dogshoot' attack type, shoots when out of reach, melee attack when in reach, also api tweaks and self.reach added 1.16- Mobs follow multiple items now, Npc's can breed diff --git a/mods/mobs/api.lua b/mods/mobs/api.lua index 1324eb19..bf035410 100755 --- a/mods/mobs/api.lua +++ b/mods/mobs/api.lua @@ -1,4 +1,4 @@ --- Mobs Api (27th October 2015) +-- Mobs Api (4th November 2015) mobs = {} mobs.mod = "redo" @@ -146,7 +146,9 @@ function check_for_death(self) -- still got some health? play hurt sound if hp > 0 then + self.health = hp + if self.sounds.damage then minetest.sound_play(self.sounds.damage,{ pos = pos, @@ -160,10 +162,12 @@ function check_for_death(self) -- drop items when dead local obj for _,drop in ipairs(self.drops) do + if math.random(1, drop.chance) == 1 then obj = minetest.add_item(pos, ItemStack(drop.name .. " " .. math.random(drop.min, drop.max))) + if obj then obj:setvelocity({ x = math.random(-1, 1), @@ -216,6 +220,7 @@ do_env_damage = function(self) end local pos = self.object:getpos() + self.time_of_day = minetest.get_timeofday() -- remove mob if beyond map limits @@ -230,14 +235,18 @@ do_env_damage = function(self) and self.time_of_day > 0.2 and self.time_of_day < 0.8 and (minetest.get_node_light(pos) or 0) > 12 then + self.object:set_hp(self.object:get_hp() - self.light_damage) effect(pos, 5, "tnt_smoke.png") end if self.water_damage ~= 0 or self.lava_damage ~= 0 then + pos.y = (pos.y + self.collisionbox[2]) + 0.1 -- foot level + local nod = node_ok(pos, "air") ; -- print ("standing in "..nod.name) local nodef = minetest.registered_nodes[nod.name] + if not nodef then return end --MFF fix crash pos.y = pos.y + 1 @@ -251,8 +260,9 @@ do_env_damage = function(self) -- lava or fire if self.lava_damage ~= 0 and (nodef.groups.lava - or nod.name == "fire:basic_flame" - or nod.name == "fire:eternal_flame") then + or nod.name == "fire:basic_flame" + or nod.name == "fire:eternal_flame" + or nod.name == "fire:permanent_flame") then self.object:set_hp(self.object:get_hp() - self.lava_damage) effect(pos, 5, "fire_basic_flame.png") end @@ -264,7 +274,8 @@ end -- jump if facing a solid node (not fences) do_jump = function(self) - if self.fly then + if self.fly + or self.child then return end @@ -329,6 +340,17 @@ in_fov = function(self, pos) return true end +function calc_velocity(pos1, pos2, old_vel, power) + local vel = vector.direction(pos1, pos2) + vel = vector.normalize(vel) + vel = vector.multiply(vel, power) + local dist = vector.distance(pos1, pos2) + dist = math.max(dist, 1) + vel = vector.divide(vel, dist) + vel = vector.add(vel, old_vel) + return vel +end + -- blast damage to entities nearby (modified from TNT mod) function entity_physics(pos, radius, self) --/MFF (Crabman|06/23/2015)add self to use punch function @@ -360,11 +382,13 @@ function node_ok(pos, fallback) fallback = fallback or "default:dirt" local node = minetest.get_node_or_nil(pos) + if not node then return minetest.registered_nodes[fallback] end local nodef = minetest.registered_nodes[node.name] + if nodef then return node end @@ -402,7 +426,9 @@ local function breed(self) if self.horny == true and self.hornytimer < 240 and self.child == false then + self.hornytimer = self.hornytimer + 1 + if self.hornytimer >= 240 then self.hornytimer = 0 self.horny = false @@ -411,18 +437,22 @@ local function breed(self) -- child take 240 seconds before growing into adult if self.child == true then + self.hornytimer = self.hornytimer + 1 + if self.hornytimer > 240 then + self.child = false self.hornytimer = 0 + self.object:set_properties({ textures = self.base_texture, mesh = self.base_mesh, visual_size = self.base_size, collisionbox = self.base_colbox, }) - -- jump when grown so not to fall into ground - local v = self.object:getvelocity() + + -- jump when fully grown so not to fall into ground self.object:setvelocity({ x = 0, y = self.jump_height, @@ -434,25 +464,33 @@ local function breed(self) -- find another same animal who is also horny and mate if close enough if self.horny == true and self.hornytimer <= 40 then + local pos = self.object:getpos() effect({x = pos.x, y = pos.y + 1, z = pos.z}, 4, "heart.png") + local ents = minetest.get_objects_inside_radius(pos, 3) local num = 0 local ent = nil + for i, obj in ipairs(ents) do + ent = obj:get_luaentity() -- check for same animal with different colour local canmate = false + if ent then + if ent.name == self.name then canmate = true else local entname = string.split(ent.name,":") local selfname = string.split(self.name,":") + if entname[1] == selfname[1] then entname = string.split(entname[2],"_") selfname = string.split(selfname[2],"_") + if entname[1] == selfname[1] then canmate = true end @@ -469,16 +507,21 @@ local function breed(self) -- found your mate? then have a baby if num > 1 then + self.hornytimer = 41 ent.hornytimer = 41 + -- spawn baby minetest.after(7, function(dtime) + local mob = minetest.add_entity(pos, self.name) local ent2 = mob:get_luaentity() local textures = self.base_texture + if self.child_texture then textures = self.child_texture[1] end + mob:set_properties({ textures = textures, visual_size = { @@ -625,7 +668,9 @@ minetest.register_entity(name, { if self.type ~= "npc" and not self.tamed and self.state ~= "attack" then + self.lifetimer = self.lifetimer - dtime + if self.lifetimer <= 0 then minetest.log("action", "lifetimer expired, removed " .. self.name) @@ -671,7 +716,9 @@ minetest.register_entity(name, { -- fall damage if self.fall_damage == 1 and self.object:getvelocity().y == 0 then + local d = self.old_y - self.object:getpos().y + if d > 5 then self.object:set_hp(self.object:get_hp() - math.floor(d - 5)) effect(pos, 5, "tnt_smoke.png") @@ -717,6 +764,7 @@ minetest.register_entity(name, { -- environmental damage timer (every 1 second) self.env_damage_timer = self.env_damage_timer + dtime + if self.state == "attack" and self.env_damage_timer > 1 then self.env_damage_timer = 0 @@ -725,6 +773,7 @@ minetest.register_entity(name, { if self.do_custom then self.do_custom(self) end + elseif self.state ~= "attack" then self.env_damage_timer = 0 do_env_damage(self) @@ -769,6 +818,7 @@ minetest.register_entity(name, { p.y = p.y + 1 sp.y = sp.y + 1 -- aim higher to make looking up hills more realistic dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5 + if dist < self.view_range then -- and self.in_fov(self,p) then -- choose closest player to attack @@ -793,11 +843,15 @@ minetest.register_entity(name, { if self.type == "npc" and self.attacks_monsters and self.state ~= "attack" then + local s = self.object:getpos() local p, dist --MFF local obj = nil + for _, oir in pairs(minetest.get_objects_inside_radius(s,self.view_range)) do + obj = oir:get_luaentity() + if obj and obj.type == "monster" then -- attack monster @@ -809,6 +863,7 @@ minetest.register_entity(name, { end end end + if min_player then do_attack(self, min_player) end @@ -865,6 +920,7 @@ minetest.register_entity(name, { end if p then + local dist = ((p.x - s.x) ^ 2 + (p.y - s.y) ^ 2 + (p.z - s.z) ^ 2) ^ 0.5 -- dont follow if out of range @@ -909,6 +965,7 @@ minetest.register_entity(name, { if self.state == "stand" then if math.random(1, 4) == 1 then + local lp = nil local s = self.object:getpos() @@ -954,6 +1011,7 @@ minetest.register_entity(name, { end elseif self.state == "walk" then + local s = self.object:getpos() local lp = minetest.find_node_near(s, 1, {"group:water"}) @@ -995,6 +1053,7 @@ minetest.register_entity(name, { set_velocity(self, self.walk_velocity) set_animation(self, "walk") + if math.random(1, 100) <= 30 then set_velocity(self, 0) self.state = "stand" @@ -1102,8 +1161,9 @@ minetest.register_entity(name, { local p2 = p local p_y = math.floor(p2.y + 1) local v = self.object:getvelocity() - if nod - and nod.name == self.fly_in then + + if nod.name == self.fly_in then + if me_y < p_y then self.object:setvelocity({ x = v.x, @@ -1243,7 +1303,9 @@ minetest.register_entity(name, { -- load entity variables if staticdata then + local tmp = minetest.deserialize(staticdata) + if tmp then for _,stat in pairs(tmp) do self[_] = stat @@ -1281,13 +1343,16 @@ minetest.register_entity(name, { -- set child objects to half size if self.child == true then + vis_size = { x = self.base_size.x / 2, y = self.base_size.y / 2 } + if def.child_texture then textures = def.child_texture[1] end + colbox = { self.base_colbox[1] / 2, self.base_colbox[2] / 2, @@ -1330,6 +1395,7 @@ minetest.register_entity(name, { self.state = "stand" local tmp = {} + for _,stat in pairs(self) do local t = type(stat) if t ~= 'function' @@ -1343,10 +1409,12 @@ minetest.register_entity(name, { end, on_punch = function(self, hitter, tflp, tool_capabilities, dir) + -- weapon wear hitter:set_detach() --MFF (crabman|27/7/2015) anti usebug, immortal if attached local weapon = hitter:get_wielded_item() local punch_interval = tool_capabilities.full_punch_interval or 1.4 + if weapon:get_definition().tool_capabilities ~= nil then local wear = math.floor((punch_interval / 75) * 9000) weapon:add_wear(wear) @@ -1355,7 +1423,9 @@ minetest.register_entity(name, { -- weapon sounds if weapon:get_definition().sounds ~= nil then + local s = math.random(0, #weapon:get_definition().sounds) + minetest.sound_play(weapon:get_definition().sounds[s], { object = hitter, max_hear_distance = 8 @@ -1382,34 +1452,46 @@ minetest.register_entity(name, { -- knock back effect if self.knock_back > 0 then + local kb = self.knock_back local r = self.recovery_time local v = self.object:getvelocity() + if tflp < punch_interval then + if kb > 0 then kb = kb * (tflp / punch_interval) end + r = r * (tflp / punch_interval) end + self.object:setvelocity({ x = dir.x * kb, y = 0, z = dir.z * kb }) + self.pause_timer = r end -- attack puncher and call other mobs for help if self.passive == false and not self.tamed then + if self.state ~= "attack" then do_attack(self, hitter) end + -- alert others to the attack local obj = nil + for _, oir in pairs(minetest.get_objects_inside_radius(hitter:getpos(), 5)) do + obj = oir:get_luaentity() + if obj then + if obj.group_attack == true and not obj.tamed --MFF(crabman) group tamed don't attack and obj.state ~= "attack" then @@ -1427,7 +1509,8 @@ end -- END mobs:register_mob function mobs.spawning_mobs = {} -function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, spawn_in_area) --MFF crabman +function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, + interval, chance, active_object_count, min_height, max_height, spawn_in_area) --MFF crabman mobs.spawning_mobs[name] = true -- chance override in minetest.conf for registered mob @@ -1442,7 +1525,9 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter neighbors = neighbors, interval = interval, chance = chance, + action = function(pos, node, _, active_object_count_wider) + -- do not spawn if too many active entities in area if active_object_count_wider > active_object_count or not mobs.spawning_mobs[name] @@ -1453,7 +1538,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter -- spawn above node pos.y = pos.y + 1 - -- mobs cannot spawn inside protected areas if enabled + -- mobs cannot spawn in protected areas when enabled if mobs.protected == 1 and minetest.is_protected(pos, "") and not spawn_in_area then --MFF crabman @@ -1470,20 +1555,18 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, inter return end - -- are we spawning inside a solid node? + -- are we spawning inside solid nodes? if minetest.registered_nodes[node_ok(pos).name].walkable == true then return end + pos.y = pos.y + 1 + if minetest.registered_nodes[node_ok(pos).name].walkable == true then return end - if minetest.setting_getbool("display_mob_spawn") then - minetest.chat_send_all("[mobs] Add "..name.." at "..minetest.pos_to_string(pos)) - end - - -- spawn mob half block higher + -- spawn mob half block higher then ground pos.y = pos.y - 0.5 minetest.add_entity(pos, name) --print ("Spawned "..name.." at "..minetest.pos_to_string(pos).." on "..node.name.." near "..neighbors[1]) @@ -1494,14 +1577,17 @@ end -- compatibility with older mob registration function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height) - mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, chance, active_object_count, -31000, max_height) + + mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30, + chance, active_object_count, -31000, max_height) end --- explosion +-- explosion (cannot break protected or unbreakable nodes) function mobs:explosion(pos, radius, fire, smoke, sound) - -- node hit, bursts into flame (cannot blast through unbreakable/specific nodes) - if not fire then fire = 0 end - if not smoke then smoke = 0 end + + fire = fire or 0 + smoke = smoke or 0 + local pos = vector.round(pos) local vm = VoxelManip() local minp, maxp = vm:read_from_map(vector.subtract(pos, radius), vector.add(pos, radius)) @@ -1513,6 +1599,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound) local c_obsidian = minetest.get_content_id("default:obsidian") local c_brick = minetest.get_content_id("default:obsidianbrick") local c_chest = minetest.get_content_id("default:chest_locked") + + -- explosion sound if sound and sound ~= "" then minetest.sound_play(sound, { @@ -1521,15 +1609,18 @@ function mobs:explosion(pos, radius, fire, smoke, sound) max_hear_distance = 16 }) end - -- if area protected or at map limits then no blast damage + + -- if area protected or near map limits then no blast damage if minetest.is_protected(pos, "") or not within_limits(pos, radius) then return end + for z = -radius, radius do for y = -radius, radius do local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z) for x = -radius, radius do + p.x = pos.x + x p.y = pos.y + y p.z = pos.z + z @@ -1539,6 +1630,7 @@ function mobs:explosion(pos, radius, fire, smoke, sound) and data[vi] ~= c_obsidian and data[vi] ~= c_brick and data[vi] ~= c_chest then + local n = node_ok(p).name if not minetest.is_protected(p, "") --/MFF (Crabman|06/23/2015) re-added node protected in areas and minetest.get_item_group(n, "unbreakable") ~= 1 @@ -1546,11 +1638,15 @@ function mobs:explosion(pos, radius, fire, smoke, sound) -- if chest then drop items inside if n == "default:chest" or n == "3dchest:chest" then + local meta = minetest.get_meta(p) local inv = meta:get_inventory() - for i = 1,32 do + + for i = 1, 32 do + local m_stack = inv:get_stack("main", i) local obj = minetest.add_item(p, m_stack) + if obj then obj:setvelocity({ x = math.random(-2, 2), @@ -1560,6 +1656,8 @@ function mobs:explosion(pos, radius, fire, smoke, sound) end end end + + -- after effects if fire > 0 and (minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 30) then @@ -1567,6 +1665,7 @@ function mobs:explosion(pos, radius, fire, smoke, sound) else minetest.remove_node(p) end + if smoke > 0 then effect(p, 2, "tnt_smoke.png", 5) end @@ -1580,7 +1679,9 @@ end -- register arrow for shoot attack function mobs:register_arrow(name, def) + if not name or not def then return end -- errorcheck + minetest.register_entity(name, { physical = false, visual = def.visual, @@ -1595,8 +1696,11 @@ function mobs:register_arrow(name, def) timer = 0, on_step = function(self, dtime) + self.timer = self.timer + 1 + local pos = self.object:getpos() + if self.timer > 150 or not within_limits(pos, 0) then self.object:remove() ; -- print ("removed arrow") @@ -1604,15 +1708,21 @@ function mobs:register_arrow(name, def) end if self.hit_node then + local node = node_ok(pos).name + if minetest.registered_nodes[node].walkable then + self.hit_node(self, pos, node) + if self.drop == true then pos.y = pos.y + 1 self.lastpos = (self.lastpos or pos) minetest.add_item(self.lastpos, self.object:get_luaentity().name) end + self.object:remove() ; -- print ("hit node") + return end end @@ -1620,19 +1730,24 @@ function mobs:register_arrow(name, def) if (self.hit_player or self.hit_mob) -- clear mob entity before arrow becomes active and self.timer > (10 - (self.velocity / 2)) then + for _,player in pairs(minetest.get_objects_inside_radius(pos, 1.0)) do + if self.hit_player and player:is_player() then + self.hit_player(self, player) self.object:remove() ; -- print ("hit player") return end + if self.hit_mob and player:get_luaentity() and player:get_luaentity().name ~= self.object:get_luaentity().name and player:get_luaentity().name ~= "__builtin:item" and player:get_luaentity().name ~= "gauges:hp_bar" and player:get_luaentity().name ~= "signs:text" then + self.hit_mob(self, player) self.object:remove() ; -- print ("hit mob") return @@ -1646,30 +1761,42 @@ end -- Spawn Egg function mobs:register_egg(mob, desc, background, addegg) + local invimg = background + if addegg == 1 then - invimg = invimg.."^mobs_chicken_egg.png" + invimg = invimg .. "^mobs_chicken_egg.png" end + minetest.register_craftitem(mob, { description = desc, inventory_image = invimg, + on_place = function(itemstack, placer, pointed_thing) + local pos = pointed_thing.above - if pos and within_limits(pos, 0) + + if pos + and within_limits(pos, 0) and not minetest.is_protected(pos, placer:get_player_name()) then + pos.y = pos.y + 1 + local mob = minetest.add_entity(pos, mob) local ent = mob:get_luaentity() + if ent.type ~= "monster" then - -- set owner and tame + -- set owner and tame if not monster ent.owner = placer:get_player_name() ent.tamed = true end + -- if not in creative then take item if not minetest.setting_getbool("creative_mode") then itemstack:take_item() end end + return itemstack end, }) @@ -1677,22 +1804,28 @@ end -- capture critter (thanks to blert2112 for idea) function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, force_take, replacewith) - if clicker:is_player() - and clicker:get_inventory() - and not self.child then + + if not self.child + and clicker:is_player() + and clicker:get_inventory() then + -- get name of clicked mob local mobname = self.name + -- if not nil change what will be added to inventory if replacewith then mobname = replacewith end + local name = clicker:get_player_name() + -- is mob tamed? if self.tamed == false and force_take == false then minetest.chat_send_player(name, "Not tamed!") return end + -- cannot pick up if not owner if self.owner ~= name and force_take == false then @@ -1701,26 +1834,30 @@ function mobs:capture_mob(self, clicker, chance_hand, chance_net, chance_lasso, end if clicker:get_inventory():room_for_item("main", mobname) then + -- was mob clicked with hand, net, or lasso? local tool = clicker:get_wielded_item() local chance = 0 + if tool:is_empty() then chance = chance_hand + elseif tool:get_name() == "mobs:net" then chance = chance_net tool:add_wear(4000) -- 17 uses clicker:set_wielded_item(tool) + elseif tool:get_name() == "mobs:magic_lasso" then - -- pick up if owner chance = chance_lasso tool:add_wear(650) -- 100 uses clicker:set_wielded_item(tool) end + -- return if no chance if chance == 0 then return end - -- calculate chance.. was capture successful? - if math.random(100) <= chance then - -- successful capture.. add to inventory + + -- calculate chance.. add to inventory if successful? + if math.random(1, 100) <= chance then clicker:get_inventory():add_item("main", mobname) self.object:remove() else diff --git a/mods/mobs/chicken.lua b/mods/mobs/chicken.lua index 67ff3c6e..7329ffca 100755 --- a/mods/mobs/chicken.lua +++ b/mods/mobs/chicken.lua @@ -54,18 +54,122 @@ mobs:register_mob("mobs:chicken", { -- follows wheat follow = {"farming:seed_wheat", "farming:seed_cotton"}, view_range = 8, - replace_rate = 2500, - replace_what = {"air"}, - replace_with = "mobs:egg", + on_rightclick = function(self, clicker) mobs:feed_tame(self, clicker, 8, true, true) mobs:capture_mob(self, clicker, 30, 50, 80, false, nil) end, + + do_custom = function(self) + if not self.child + and math.random(1, 500) == 1 then + local pos = self.object:getpos() + minetest.add_item(pos, "mobs:egg") + minetest.sound_play("default_place_node_hard", { + pos = pos, + gain = 1.0, + max_hear_distance = 5, + }) + end + end, }) -- spawn on default or bamboo grass between 8 and 20 light, 1 in 10000 change, 1 chicken in area up to 31000 in height mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true) -- register spawn egg mobs:register_egg("mobs:chicken", "Chicken", "mobs_chicken_inv.png", 1) +-- egg entity + +mobs:register_arrow("mobs:egg_entity", { + visual = "sprite", + visual_size = {x=.5, y=.5}, + textures = {"mobs_chicken_egg.png"}, + velocity = 6, + + hit_player = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_mob = function(self, player) + player:punch(self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_node = function(self, pos, node) + + local num = math.random(1, 10) + if num == 1 then + pos.y = pos.y + 1 + local nod = minetest.get_node_or_nil(pos) + if not nod + or not minetest.registered_nodes[nod.name] + or minetest.registered_nodes[nod.name].walkable == true then + return + end + local mob = minetest.add_entity(pos, "mobs:chicken") + local ent2 = mob:get_luaentity() + mob:set_properties({ + textures = ent2.child_texture[1], + visual_size = { + x = ent2.base_size.x / 2, + y = ent2.base_size.y / 2 + }, + collisionbox = { + ent2.base_colbox[1] / 2, + ent2.base_colbox[2] / 2, + ent2.base_colbox[3] / 2, + ent2.base_colbox[4] / 2, + ent2.base_colbox[5] / 2, + ent2.base_colbox[6] / 2 + }, + }) + ent2.child = true + ent2.tamed = true + ent2.owner = self.playername + end + end +}) + +-- snowball throwing item + +local egg_GRAVITY = 9 +local egg_VELOCITY = 19 + +-- shoot snowball +local mobs_shoot_egg = function (item, player, pointed_thing) + local playerpos = player:getpos() + minetest.sound_play("default_place_node_hard", { + pos = playerpos, + gain = 1.0, + max_hear_distance = 5, + }) + local obj = minetest.add_entity({ + x = playerpos.x, + y = playerpos.y +1.5, + z = playerpos.z + }, "mobs:egg_entity") + local dir = player:get_look_dir() + obj:get_luaentity().velocity = egg_VELOCITY -- needed for api internal timing + obj:setvelocity({ + x = dir.x * egg_VELOCITY, + y = dir.y * egg_VELOCITY, + z = dir.z * egg_VELOCITY + }) + obj:setacceleration({ + x = dir.x * -3, + y = -egg_GRAVITY, + z = dir.z * -3 + }) + -- pass player name to egg for chick ownership + local ent2 = obj:get_luaentity() + ent2.playername = player:get_player_name() + item:take_item() + return item +end -- egg minetest.register_node("mobs:egg", { @@ -83,12 +187,13 @@ minetest.register_node("mobs:egg", { type = "fixed", fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} }, - groups = {snappy=2, dig_immediate=3}, + groups = {snappy = 2, dig_immediate = 3}, after_place_node = function(pos, placer, itemstack) if placer:is_player() then minetest.set_node(pos, {name = "mobs:egg", param2 = 1}) end - end + end, + on_use = mobs_shoot_egg }) -- fried egg @@ -104,7 +209,7 @@ minetest.register_craft({ output = "mobs:chicken_egg_fried", }) --- chicken (raw and cooked) +-- raw chicken minetest.register_craftitem("mobs:chicken_raw", { description = "Raw Chicken", inventory_image = "mobs_chicken_raw.png", @@ -122,4 +227,4 @@ minetest.register_craft({ type = "cooking", recipe = "mobs:chicken_raw", output = "mobs:chicken_cooked", -}) +}) \ No newline at end of file diff --git a/mods/mobs/sheep.lua b/mods/mobs/sheep.lua index 72c99839..84aeac67 100755 --- a/mods/mobs/sheep.lua +++ b/mods/mobs/sheep.lua @@ -168,6 +168,7 @@ minetest.register_entity("mobs:sheep", { end, on_step = function(self, dtime) + self.timer = self.timer + dtime if self.timer >= 1 then self.timer = 0 @@ -179,18 +180,4 @@ minetest.register_entity("mobs:sheep", { end end, -}) - --- -- shears (right click sheep to shear wool) --- minetest.register_tool("mobs:shears", { --- description = "Steel Shears (right-click sheep to shear)", --- inventory_image = "mobs_shears.png", --- tool_capabilities = { -- Modif MFF /DEBUT --- full_punch_interval = 1, --- max_drop_level=1, --- groupcaps={ --- snappy={times={[1]=2.5, [2]=1.20, [3]=0.35}, uses=30, maxlevel=2}, --- }, --- damage_groups = {fleshy=0}, --- } --- }) -- Modif MFF /FIN +}) \ No newline at end of file