diff --git a/mobs_animal/chicken.lua b/mobs_animal/chicken.lua new file mode 100644 index 0000000..11e2107 --- /dev/null +++ b/mobs_animal/chicken.lua @@ -0,0 +1,306 @@ + +local S = mobs.intllib + + +-- Chicken by JK Murray and Sirrobzeroone + +mobs:register_mob("mobs_animal:chicken", { +stepheight = 0.6, + type = "animal", + passive = true, + hp_min = 5, + hp_max = 10, + armor = 200, + collisionbox = {-0.3, -0.75, -0.3, 0.3, 0.1, 0.3}, + visual = "mesh", + mesh = "mobs_chicken.b3d", + textures = { + {"mobs_chicken.png"}, -- white + {"mobs_chicken_brown.png"}, + {"mobs_chicken_black.png"}, + }, + child_texture = { + {"mobs_chick.png"}, + }, + makes_footstep_sound = true, + sounds = { + random = "mobs_chicken", + }, + walk_velocity = 1, + run_velocity = 3, + runaway = true, + runaway_from = {"player", "mobs_animal:pumba"}, + drops = { + {name = "mobs:chicken_raw", chance = 1, min = 1, max = 1}, + {name = "mobs:chicken_feather", chance = 1, min = 0, max = 2}, + }, + water_damage = 1, + lava_damage = 5, + light_damage = 0, + fall_damage = 0, + fall_speed = -8, + fear_height = 5, + animation = { + speed_normal = 15, + stand_start = 1, + stand_end = 30, + stand_speed = 28, + stand1_start = 31, + stand1_end = 70, + stand1_speed = 32, + walk_start = 71, + walk_end = 90, + walk_speed = 24, + run_start = 91, + run_end = 110, + run_speed = 24, + }, + follow = {"farming:seed_wheat", "farming:seed_cotton"}, + view_range = 5, + + on_rightclick = function(self, clicker) + + if mobs:feed_tame(self, clicker, 8, true, true) then return end + if mobs:protect(self, clicker) then return end + if mobs:capture_mob(self, clicker, 30, 50, 80, false, nil) then return end + end, + + do_custom = function(self, dtime) + + self.egg_timer = (self.egg_timer or 0) + dtime + if self.egg_timer < 10 then + return + end + self.egg_timer = 0 + + if self.child + or math.random(1, 100) > 1 then + return + end + + local pos = self.object:get_pos() + + minetest.add_item(pos, "mobs:egg") + + minetest.sound_play("default_place_node_hard", { + pos = pos, + gain = 1.0, + max_hear_distance = 5, + }) + end, +}) + + +local spawn_on = "default:dirt_with_grass" + +if minetest.get_modpath("ethereal") then + spawn_on = "ethereal:bamboo_dirt" +end + +mobs:spawn({ + name = "mobs_animal:chicken", + nodes = {spawn_on}, + neighbors = {"group:grass"}, + min_light = 14, + interval = 60, + chance = 8000, -- 15000 + min_height = 5, + max_height = 200, + day_toggle = true, +}) + + +mobs:register_egg("mobs_animal:chicken", S("Chicken"), "mobs_chicken_inv.png", 0) + + +mobs:alias_mob("mobs:chicken", "mobs_animal:chicken") -- compatibility + + +-- egg entity + +mobs:register_arrow("mobs_animal:egg_entity", { + visual = "sprite", + visual_size = {x=.5, y=.5}, + textures = {"mobs_chicken_egg.png"}, + velocity = 6, + + hit_player = function(self, player) + player:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_mob = function(self, player) + player:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, { + full_punch_interval = 1.0, + damage_groups = {fleshy = 1}, + }, nil) + end, + + hit_node = function(self, pos, node) + + if math.random(1, 10) > 1 then + return + end + + 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_animal: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 +}) + + +-- egg throwing item + +local egg_GRAVITY = 9 +local egg_VELOCITY = 19 + +-- shoot egg +local mobs_shoot_egg = function (item, player, pointed_thing) + + local playerpos = player:get_pos() + + 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_animal:egg_entity") + + local ent = obj:get_luaentity() + local dir = player:get_look_dir() + + ent.velocity = egg_VELOCITY -- needed for api internal timing + ent.switch = 1 -- needed so that egg doesn't despawn straight away + + 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", { + description = S("Chicken Egg"), + tiles = {"mobs_chicken_egg.png"}, + inventory_image = "mobs_chicken_egg.png", + visual_scale = 0.7, + drawtype = "plantlike", + wield_image = "mobs_chicken_egg.png", + paramtype = "light", + walkable = false, + is_ground_content = true, + sunlight_propagates = true, + selection_box = { + type = "fixed", + fixed = {-0.2, -0.5, -0.2, 0.2, 0, 0.2} + }, + groups = {food_egg = 1, 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, + on_use = mobs_shoot_egg +}) + + +-- fried egg +minetest.register_craftitem(":mobs:chicken_egg_fried", { + description = S("Fried Egg"), + inventory_image = "mobs_chicken_egg_fried.png", + on_use = minetest.item_eat(2), + groups = {food_egg_fried = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "cooking", + recipe = "mobs:egg", + output = "mobs:chicken_egg_fried", +}) + +-- raw chicken +minetest.register_craftitem(":mobs:chicken_raw", { +description = S("Raw Chicken"), + inventory_image = "mobs_chicken_raw.png", + on_use = minetest.item_eat(2), + groups = {food_meat_raw = 1, food_chicken_raw = 1, flammable = 2}, +}) + +-- cooked chicken +minetest.register_craftitem(":mobs:chicken_cooked", { +description = S("Cooked Chicken"), + inventory_image = "mobs_chicken_cooked.png", + on_use = minetest.item_eat(6), + groups = {food_meat = 1, food_chicken = 1, flammable = 2}, +}) + +minetest.register_craft({ + type = "cooking", + recipe = "mobs:chicken_raw", + output = "mobs:chicken_cooked", +}) + +-- feather +minetest.register_craftitem(":mobs:chicken_feather", { + description = S("Feather"), + inventory_image = "mobs_chicken_feather.png", + groups = {flammable = 2}, +}) + +minetest.register_craft({ + type = "fuel", + recipe = "mobs:chicken_feather", + burntime = 1, +}) diff --git a/mobs_animal/init.lua b/mobs_animal/init.lua new file mode 100644 index 0000000..0325b81 --- /dev/null +++ b/mobs_animal/init.lua @@ -0,0 +1,24 @@ + +local path = minetest.get_modpath("mobs_animal") + +-- Load support for intllib. +local MP = minetest.get_modpath(minetest.get_current_modname()) +local S, NS = dofile(MP.."/intllib.lua") +mobs.intllib = S + +-- Animals + +dofile(path .. "/chicken.lua") -- JKmurray +dofile(path .. "/cow.lua") -- KrupnoPavel +dofile(path .. "/rat.lua") -- PilzAdam +dofile(path .. "/sheep.lua") -- PilzAdam +dofile(path .. "/warthog.lua") -- KrupnoPavel +dofile(path .. "/bee.lua") -- KrupnoPavel +dofile(path .. "/bunny.lua") -- ExeterDad +dofile(path .. "/kitten.lua") -- Jordach/BFD +dofile(path .. "/penguin.lua") -- D00Med +dofile(path .. "/panda.lua") -- AspireMint + +dofile(path .. "/lucky_block.lua") + +print (S("[MOD] Mobs Redo 'Animals' loaded")) diff --git a/mobs_animal/intllib.lua b/mobs_animal/intllib.lua new file mode 100644 index 0000000..6669d72 --- /dev/null +++ b/mobs_animal/intllib.lua @@ -0,0 +1,45 @@ + +-- Fallback functions for when `intllib` is not installed. +-- Code released under Unlicense . + +-- Get the latest version of this file at: +-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua + +local function format(str, ...) + local args = { ... } + local function repl(escape, open, num, close) + if escape == "" then + local replacement = tostring(args[tonumber(num)]) + if open == "" then + replacement = replacement..close + end + return replacement + else + return "@"..open..num..close + end + end + return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl)) +end + +local gettext, ngettext +if minetest.get_modpath("intllib") then + if intllib.make_gettext_pair then + -- New method using gettext. + gettext, ngettext = intllib.make_gettext_pair() + else + -- Old method using text files. + gettext = intllib.Getter() + end +end + +-- Fill in missing functions. + +gettext = gettext or function(msgid, ...) + return format(msgid, ...) +end + +ngettext = ngettext or function(msgid, msgid_plural, n, ...) + return format(n==1 and msgid or msgid_plural, ...) +end + +return gettext, ngettext diff --git a/mobs_animal/kitten.lua b/mobs_animal/kitten.lua new file mode 100644 index 0000000..2b069f3 --- /dev/null +++ b/mobs_animal/kitten.lua @@ -0,0 +1,167 @@ + +local S = mobs.intllib +local hairball = minetest.settings:get("mobs_hairball") + +-- Kitten by Jordach / BFD + +mobs:register_mob("mobs_animal:kitten", { +stepheight = 0.6, + type = "animal", +specific_attack = {"mobs_animal:rat"}, +damage = 1, +attack_type = "dogfight", +attack_animals = true, -- so it can attack rat +attack_players = false, +reach = 1, + passive = false, + hp_min = 5, + hp_max = 10, + armor = 200, + collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.1, 0.3}, + visual = "mesh", + visual_size = {x = 0.5, y = 0.5}, + mesh = "mobs_kitten.b3d", + textures = { + {"mobs_kitten_striped.png"}, + {"mobs_kitten_splotchy.png"}, + {"mobs_kitten_ginger.png"}, + {"mobs_kitten_sandy.png"}, + }, + makes_footstep_sound = false, + sounds = { + random = "mobs_kitten", + }, + walk_velocity = 0.6, + walk_chance = 15, + run_velocity = 2, + runaway = true, + jump = false, + drops = { + {name = "farming:string", chance = 1, min = 0, max = 1}, + }, + water_damage = 0, + lava_damage = 5, + fear_height = 3, + animation = { + speed_normal = 42, + stand_start = 97, + stand_end = 192, + walk_start = 0, + walk_end = 96, + stoodup_start = 0, + stoodup_end = 0, + }, + follow = {"mobs_animal:rat", "ethereal:fish_raw", "mobs_fish:clownfish", "mobs_fish:tropical"}, + view_range = 8, + + on_rightclick = function(self, clicker) + + if mobs:feed_tame(self, clicker, 4, true, true) then return end + if mobs:protect(self, clicker) then return end + if mobs:capture_mob(self, clicker, 50, 50, 90, false, nil) then return end + + -- by right-clicking owner can switch between staying and walking + if self.owner and self.owner == clicker:get_player_name() then + + if self.order ~= "stand" then + self.order = "stand" + self.state = "stand" + self.object:set_velocity({x = 0, y = 0, z = 0}) + mobs:set_animation(self, "stand") + else + self.order = "" + mobs:set_animation(self, "stoodup") + end + end + end, + + do_custom = function(self, dtime) + + if hairball == "false" then + return + end + + self.hairball_timer = (self.hairball_timer or 0) + dtime + if self.hairball_timer < 10 then + return + end + self.hairball_timer = 0 + + if self.child + or math.random(1, 250) > 1 then + return + end + + local pos = self.object:get_pos() + + minetest.add_item(pos, "mobs:hairball") + + minetest.sound_play("default_dig_snappy", { + pos = pos, + gain = 1.0, + max_hear_distance = 5, + }) + end, +}) + + +local spawn_on = "default:dirt_with_grass" + +if minetest.get_modpath("ethereal") then + spawn_on = "ethereal:grove_dirt" +end + +mobs:spawn({ + name = "mobs_animal:kitten", + nodes = {spawn_on}, + neighbors = {"group:grass"}, + min_light = 14, + interval = 60, + chance = 10000, -- 22000 + min_height = 5, + max_height = 50, + day_toggle = true, +}) + + +mobs:register_egg("mobs_animal:kitten", S("Kitten"), "mobs_kitten_inv.png", 0) + + +mobs:alias_mob("mobs:kitten", "mobs_animal:kitten") -- compatibility + + +local hairball_items = { + "default:stick", "default:coal_lump", "default:dry_shrub", "flowers:rose", + "mobs_animal:rat", "default:grass_1", "farming:seed_wheat", "dye:green", "", + "farming:seed_cotton", "default:flint", "default:sapling", "dye:white", "", + "default:clay_lump", "default:paper", "default:dry_grass_1", "dye:red", "", + "farming:string", "mobs:chicken_feather", "default:acacia_bush_sapling", "", + "default:bush_sapling", "default:copper_lump", "default:iron_lump", "", + "dye:black", "dye:brown", "default:obsidian_shard", "default:tin_lump" +} + +minetest.register_craftitem(":mobs:hairball", { + description = S("Hairball"), + inventory_image = "mobs_hairball.png", + on_use = function(itemstack, user, pointed_thing) + + local pos = user:get_pos() + local dir = user:get_look_dir() + local newpos = {x = pos.x + dir.x, y = pos.y + dir.y + 1.5, z = pos.z + dir.z} + local item = hairball_items[math.random(1, #hairball_items)] + + if item ~= "" then + minetest.add_item(newpos, {name = item}) + end + + minetest.sound_play("default_place_node_hard", { + pos = newpos, + gain = 1.0, + max_hear_distance = 5, + }) + + itemstack:take_item() + + return itemstack + end, +}) diff --git a/mobs_animal/license.txt b/mobs_animal/license.txt new file mode 100644 index 0000000..6411da4 --- /dev/null +++ b/mobs_animal/license.txt @@ -0,0 +1,25 @@ +The MIT License (MIT) + +Copyright (c) 2014 Krupnov Pavel and 2016 TenPlus1 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Chicken sounds from freesounds.org under CC0 + +Mutton, Pork and Rabbit meat textures by Piezo_ under CC0