mirror of
				https://github.com/ElCeejo/animalia
				synced 2025-11-04 04:03:05 +01:00 
			
		
		
		
	New Mobs, Switch to Creatura
This commit is contained in:
		
							parent
							
								
									1450e131fa
								
							
						
					
					
						commit
						e773fab121
					
				
							
								
								
									
										2460
									
								
								api/api.lua
									
									
									
									
									
								
							
							
						
						
									
										2460
									
								
								api/api.lua
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1582
									
								
								api/behaviors.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1582
									
								
								api/behaviors.lua
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										360
									
								
								api/lasso.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										360
									
								
								api/lasso.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,360 @@
 | 
			
		||||
-----------
 | 
			
		||||
-- Lasso --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
local abs = math.abs
 | 
			
		||||
 | 
			
		||||
function animalia.initialize_lasso(self)
 | 
			
		||||
    self.lasso_origin = self:recall("lasso_origin") or nil
 | 
			
		||||
    if self.lasso_origin then
 | 
			
		||||
        self.caught_with_lasso = true
 | 
			
		||||
        if type(self.lasso_origin) == "table"
 | 
			
		||||
        and minetest.get_item_group(minetest.get_node(self.lasso_origin).name, "fence") > 0 then
 | 
			
		||||
            local object = minetest.add_entity(self.lasso_origin, "animalia:lasso_fence_ent")
 | 
			
		||||
            object:get_luaentity().parent = self.object
 | 
			
		||||
        elseif type(self.lasso_origin) == "string"
 | 
			
		||||
        and minetest.get_player_by_name(self.lasso_origin) then
 | 
			
		||||
            self.lasso_origin = minetest.get_player_by_name(self.lasso_origin)
 | 
			
		||||
        else
 | 
			
		||||
            self:forget("lasso_origin")
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.set_lasso_visual(self, target)
 | 
			
		||||
    if not creatura.is_alive(self)
 | 
			
		||||
    or (self.lasso_visual
 | 
			
		||||
    and self.lasso_visual:get_luaentity()) then return end
 | 
			
		||||
    local pos = self.object:get_pos()
 | 
			
		||||
    local object = minetest.add_entity(pos, "animalia:lasso_visual")
 | 
			
		||||
    local ent = object:get_luaentity()
 | 
			
		||||
    self.lasso_visual = object
 | 
			
		||||
    self.lasso_origin = target
 | 
			
		||||
    ent.parent = self.object
 | 
			
		||||
    ent.lasso_origin = target
 | 
			
		||||
    return object
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.update_lasso_effects(self)
 | 
			
		||||
    if not creatura.is_alive(self) then return end
 | 
			
		||||
    if self.caught_with_lasso
 | 
			
		||||
    and self.lasso_origin then
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        pos.y = pos.y + (self:get_height() * 0.5)
 | 
			
		||||
        animalia.set_lasso_visual(self, self.lasso_origin)
 | 
			
		||||
        if type(self.lasso_origin) == "userdata"
 | 
			
		||||
        or type(self.lasso_origin) == "string" then
 | 
			
		||||
            if type(self.lasso_origin) == "string" then
 | 
			
		||||
                self.lasso_origin = minetest.get_player_by_name(self.lasso_origin)
 | 
			
		||||
                if not self.lasso_origin then
 | 
			
		||||
                    self.caught_with_lasso = nil
 | 
			
		||||
                    self.lasso_origin = nil
 | 
			
		||||
                    self:forget("lasso_origin")
 | 
			
		||||
                    if self.lasso_visual then
 | 
			
		||||
                        self.lasso_visual:remove()
 | 
			
		||||
                        self.lasso_visual = nil
 | 
			
		||||
                    end
 | 
			
		||||
                    return
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
            self:memorize("lasso_origin", self.lasso_origin:get_player_name())
 | 
			
		||||
            -- Get distance to lasso player
 | 
			
		||||
            local player = self.lasso_origin
 | 
			
		||||
            local lasso_origin = player:get_pos()
 | 
			
		||||
            lasso_origin.y = lasso_origin.y + 1
 | 
			
		||||
            local dist = vector.distance(pos, lasso_origin)
 | 
			
		||||
            if player:get_wielded_item():get_name() ~= "animalia:lasso"
 | 
			
		||||
            or vector.distance(pos, lasso_origin) > 16 then
 | 
			
		||||
                self.caught_with_lasso = nil
 | 
			
		||||
                self.lasso_origin = nil
 | 
			
		||||
                self:forget("lasso_origin")
 | 
			
		||||
                if self.lasso_visual then
 | 
			
		||||
                    self.lasso_visual:remove()
 | 
			
		||||
                    self.lasso_visual = nil
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
            -- Apply physics
 | 
			
		||||
            if dist > 6
 | 
			
		||||
            or abs(lasso_origin.y - pos.y) > 8 then
 | 
			
		||||
                local p_target = vector.add(pos, vector.multiply(vector.direction(pos, lasso_origin), dist * 0.8))
 | 
			
		||||
                local g = -0.18
 | 
			
		||||
                local v = vector.new(0, 0, 0)
 | 
			
		||||
                v.x = (1.0 + (0.005 * dist)) * (p_target.x - pos.x) / dist
 | 
			
		||||
                v.y = -((1.0 + (0.03 * dist)) * ((lasso_origin.y - 4) - pos.y) / (dist * (g * dist)))
 | 
			
		||||
                v.z = (1.0 + (0.005 * dist)) * (p_target.z - pos.z) / dist
 | 
			
		||||
                self.object:add_velocity(v)
 | 
			
		||||
            end
 | 
			
		||||
        elseif type(self.lasso_origin) == "table" then
 | 
			
		||||
            self:memorize("lasso_origin", self.lasso_origin)
 | 
			
		||||
            local lasso_origin = self.lasso_origin
 | 
			
		||||
            local dist = vector.distance(pos, lasso_origin)
 | 
			
		||||
            if dist > 6
 | 
			
		||||
            or abs(lasso_origin.y - pos.y) > 8 then
 | 
			
		||||
                local p_target = vector.add(pos, vector.multiply(vector.direction(pos, lasso_origin), dist * 0.8))
 | 
			
		||||
                local g = -0.18
 | 
			
		||||
                local v = vector.new(0, 0, 0)
 | 
			
		||||
                v.x = (1.0 + (0.005 * dist)) * (p_target.x - pos.x) / dist
 | 
			
		||||
                v.y = -((1.0 + (0.03 * dist)) * ((lasso_origin.y - 4) - pos.y) / (dist * (g * dist)))
 | 
			
		||||
                v.z = (1.0 + (0.005 * dist)) * (p_target.z - pos.z) / dist
 | 
			
		||||
                self.object:add_velocity(v)
 | 
			
		||||
            end
 | 
			
		||||
            local objects = minetest.get_objects_inside_radius(lasso_origin, 1)
 | 
			
		||||
            local is_lasso_attached = false
 | 
			
		||||
            for _, object in ipairs(objects) do
 | 
			
		||||
                if object
 | 
			
		||||
                and object:get_luaentity()
 | 
			
		||||
                and object:get_luaentity().name == "animalia:lasso_fence_ent" then
 | 
			
		||||
                    is_lasso_attached = true
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
            if not is_lasso_attached then
 | 
			
		||||
                self.caught_with_lasso = nil
 | 
			
		||||
                self.lasso_origin = nil
 | 
			
		||||
                self:forget("lasso_origin")
 | 
			
		||||
                if self.lasso_visual then
 | 
			
		||||
                    self.lasso_visual:remove()
 | 
			
		||||
                    self.lasso_visual = nil
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        else
 | 
			
		||||
            local objects = minetest.get_objects_inside_radius(self.lasso_origin, 0.4)
 | 
			
		||||
            for _, object in ipairs(objects) do
 | 
			
		||||
                if object
 | 
			
		||||
                and object:get_luaentity()
 | 
			
		||||
                and object:get_luaentity().name == "animalia:lasso_fence_ent" then
 | 
			
		||||
                    minetest.add_item(object:get_pos(), "animalia:lasso")
 | 
			
		||||
                    object:remove()
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
            self.caught_with_lasso = nil
 | 
			
		||||
            self.lasso_origin = nil
 | 
			
		||||
            self:forget("lasso_origin")
 | 
			
		||||
            if self.lasso_visual then
 | 
			
		||||
                self.lasso_visual:remove()
 | 
			
		||||
                self.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function is_lasso_in_use(player)
 | 
			
		||||
    for _, ent in pairs(minetest.luaentities) do
 | 
			
		||||
        if ent.name
 | 
			
		||||
        and ent.name:match("^animalia:") then
 | 
			
		||||
            if ent.lasso_origin
 | 
			
		||||
            and type(ent.lasso_origin) == "userdata"
 | 
			
		||||
            and ent.lasso_origin == player then
 | 
			
		||||
                return true
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function update_lasso_rotation(self)
 | 
			
		||||
    if not self.parent
 | 
			
		||||
    or not self.lasso_origin then self.object:remove() return end
 | 
			
		||||
    local lasso_origin = self.lasso_origin
 | 
			
		||||
    if type(lasso_origin) == "userdata" then
 | 
			
		||||
        lasso_origin = lasso_origin:get_pos()
 | 
			
		||||
        lasso_origin.y = lasso_origin.y + 1
 | 
			
		||||
    end
 | 
			
		||||
    local object = self.parent
 | 
			
		||||
    if not object then return end
 | 
			
		||||
    local pos = object:get_pos()
 | 
			
		||||
    pos.y = pos.y + object:get_luaentity():get_height()
 | 
			
		||||
    local rot = vector.dir_to_rotation(vector.direction(lasso_origin, pos))
 | 
			
		||||
    self.object:set_pos(lasso_origin)
 | 
			
		||||
    self.object:set_rotation(rot)
 | 
			
		||||
    self.object:set_properties({
 | 
			
		||||
        visual_size = {x = 6, z = 10 * vector.distance(pos, lasso_origin), y = 6}
 | 
			
		||||
    })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:lasso_visual", {
 | 
			
		||||
    hp_max = 1,
 | 
			
		||||
    physical = false,
 | 
			
		||||
    collisionbox = {0, 0, 0, 0, 0, 0},
 | 
			
		||||
    visual = "mesh",
 | 
			
		||||
    mesh = "animalia_lasso.b3d",
 | 
			
		||||
    visual_size = {x = 2, y = 2},
 | 
			
		||||
    textures = {"animalia_lasso_cube.png"},
 | 
			
		||||
    is_visible = true,
 | 
			
		||||
    makes_footstep_sound = false,
 | 
			
		||||
    glow = 1,
 | 
			
		||||
    on_step = function(self, dtime)
 | 
			
		||||
        self.object:set_armor_groups({immortal = 1})
 | 
			
		||||
        if not self.parent
 | 
			
		||||
        or not self.lasso_origin
 | 
			
		||||
        or (self.parent
 | 
			
		||||
        and (not creatura.is_alive(self.parent)
 | 
			
		||||
        or not self.parent:get_luaentity().caught_with_lasso)) then
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        update_lasso_rotation(self)
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:frog_tongue_visual", {
 | 
			
		||||
    hp_max = 1,
 | 
			
		||||
    physical = false,
 | 
			
		||||
    collisionbox = {0, 0, 0, 0, 0, 0},
 | 
			
		||||
    visual = "mesh",
 | 
			
		||||
    mesh = "animalia_lasso.b3d",
 | 
			
		||||
    visual_size = {x = 2, y = 2},
 | 
			
		||||
    textures = {"animalia_frog_tongue.png"},
 | 
			
		||||
    is_visible = true,
 | 
			
		||||
    makes_footstep_sound = false,
 | 
			
		||||
    on_step = function(self, dtime)
 | 
			
		||||
        self.object:set_armor_groups({immortal = 1})
 | 
			
		||||
        if not self.parent
 | 
			
		||||
        or not self.lasso_origin
 | 
			
		||||
        or (self.parent
 | 
			
		||||
        and (not creatura.is_alive(self.parent)
 | 
			
		||||
        or not self.parent:get_luaentity().caught_with_lasso)) then
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        update_lasso_rotation(self)
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:lasso_fence_ent", {
 | 
			
		||||
    physical = false,
 | 
			
		||||
    collisionbox = {-0.25,-0.25,-0.25, 0.25,0.25,0.25},
 | 
			
		||||
    visual = "cube",
 | 
			
		||||
    visual_size = {x = 0.3, y = 0.3},
 | 
			
		||||
    mesh = "model",
 | 
			
		||||
    textures = {
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
    },
 | 
			
		||||
    makes_footstep_sound = false,
 | 
			
		||||
    on_step = function(self)
 | 
			
		||||
        if not self.parent
 | 
			
		||||
        or not self.parent:get_luaentity()
 | 
			
		||||
        or not self.parent:get_luaentity().lasso_origin then
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        local node = minetest.get_node(pos)
 | 
			
		||||
        if not minetest.registered_nodes[node.name].walkable
 | 
			
		||||
        or minetest.get_item_group(node.name, "fence") < 1 then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_origin = ent:memorize("lasso_origin", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
            minetest.add_item(self.object:get_pos(), "animalia:lasso")
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
    end,
 | 
			
		||||
    on_rightclick = function(self)
 | 
			
		||||
        if self.parent then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_origin = ent:memorize("lasso_origin", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        local dirs = {
 | 
			
		||||
            vector.new(1, 0, 0),
 | 
			
		||||
            vector.new(-1, 0, 0),
 | 
			
		||||
            vector.new(0, 1, 0),
 | 
			
		||||
            vector.new(0, -1, 0),
 | 
			
		||||
            vector.new(0, 0, 1),
 | 
			
		||||
            vector.new(0, 0, -1),
 | 
			
		||||
        }
 | 
			
		||||
        for i = 1, 6 do
 | 
			
		||||
            local pos = vector.add(self.object:get_pos(), dirs[i])
 | 
			
		||||
            local name = minetest.get_node(pos).name
 | 
			
		||||
            if not minetest.registered_nodes[name].walkable then
 | 
			
		||||
                minetest.add_item(pos, "animalia:lasso")
 | 
			
		||||
                break
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        self.object:remove()
 | 
			
		||||
    end,
 | 
			
		||||
    on_punch = function(self)
 | 
			
		||||
        if self.parent then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_origin = ent:memorize("lasso_origin", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        local dirs = {
 | 
			
		||||
            vector.new(1, 0, 0),
 | 
			
		||||
            vector.new(-1, 0, 0),
 | 
			
		||||
            vector.new(0, 1, 0),
 | 
			
		||||
            vector.new(0, -1, 0),
 | 
			
		||||
            vector.new(0, 0, 1),
 | 
			
		||||
            vector.new(0, 0, -1),
 | 
			
		||||
        }
 | 
			
		||||
        for i = 1, 6 do
 | 
			
		||||
            local pos = vector.add(self.object:get_pos(), dirs[i])
 | 
			
		||||
            local name = minetest.get_node(pos).name
 | 
			
		||||
            if not minetest.registered_nodes[name].walkable then
 | 
			
		||||
                minetest.add_item(pos, "animalia:lasso")
 | 
			
		||||
                break
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        self.object:remove()
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:lasso", {
 | 
			
		||||
    description = "Lasso",
 | 
			
		||||
    inventory_image = "animalia_lasso.png",
 | 
			
		||||
    on_secondary_use = function(itemstack, placer, pointed_thing)
 | 
			
		||||
        if pointed_thing.type == "object" then
 | 
			
		||||
            if pointed_thing.ref:is_player() then return end
 | 
			
		||||
            local ent = pointed_thing.ref:get_luaentity()
 | 
			
		||||
            if not ent.caught_with_lasso
 | 
			
		||||
            and not is_lasso_in_use(placer) then
 | 
			
		||||
                ent.caught_with_lasso = true
 | 
			
		||||
                ent.lasso_origin = placer
 | 
			
		||||
            elseif ent.lasso_origin
 | 
			
		||||
            and ent.lasso_origin == placer then
 | 
			
		||||
                ent.caught_with_lasso = nil
 | 
			
		||||
                ent.lasso_origin = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end,
 | 
			
		||||
    on_place = function(itemstack, placer, pointed_thing)
 | 
			
		||||
        if pointed_thing.type == "node" then
 | 
			
		||||
            local pos = minetest.get_pointed_thing_position(pointed_thing)
 | 
			
		||||
            if minetest.get_item_group(minetest.get_node(pos).name, "fence") > 0 then
 | 
			
		||||
                local objects = minetest.get_objects_inside_radius(placer:get_pos(), 21)
 | 
			
		||||
                for _, obj in ipairs(objects) do
 | 
			
		||||
                    if obj:get_luaentity()
 | 
			
		||||
                    and obj:get_luaentity().lasso_origin
 | 
			
		||||
                    and obj:get_luaentity().lasso_visual
 | 
			
		||||
                    and type(obj:get_luaentity().lasso_origin) == "userdata"
 | 
			
		||||
                    and obj:get_luaentity().lasso_origin == placer then
 | 
			
		||||
                        obj:get_luaentity().lasso_visual:get_luaentity().lasso_origin = pos
 | 
			
		||||
                        obj:get_luaentity().lasso_origin = pos
 | 
			
		||||
                        local object = minetest.add_entity(pos, "animalia:lasso_fence_ent")
 | 
			
		||||
                        object:get_luaentity().parent = obj
 | 
			
		||||
                        itemstack:take_item(1)
 | 
			
		||||
                        break
 | 
			
		||||
                    end
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        return itemstack
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										316
									
								
								api/spawning.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										316
									
								
								api/spawning.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,316 @@
 | 
			
		||||
--------------
 | 
			
		||||
-- Spawning --
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local path = minetest.get_modpath("animalia")
 | 
			
		||||
 | 
			
		||||
local storage = dofile(path .. "/api/storage.lua")
 | 
			
		||||
 | 
			
		||||
animalia.spawn_points = storage.spawn_points
 | 
			
		||||
 | 
			
		||||
-- Get Biomes --
 | 
			
		||||
 | 
			
		||||
local chicken_biomes = {}
 | 
			
		||||
 | 
			
		||||
local frog_biomes = {}
 | 
			
		||||
 | 
			
		||||
local pig_biomes = {}
 | 
			
		||||
 | 
			
		||||
local wolf_biomes = {}
 | 
			
		||||
 | 
			
		||||
local function insert_all(tbl, tbl2)
 | 
			
		||||
    for i = 1, #tbl2 do
 | 
			
		||||
        table.insert(tbl, tbl2[i])
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    insert_all(chicken_biomes, animalia.registered_biome_groups["grassland"].biomes)
 | 
			
		||||
    insert_all(chicken_biomes, animalia.registered_biome_groups["tropical"].biomes)
 | 
			
		||||
    insert_all(pig_biomes, animalia.registered_biome_groups["temperate"].biomes)
 | 
			
		||||
    insert_all(pig_biomes, animalia.registered_biome_groups["boreal"].biomes)
 | 
			
		||||
    insert_all(frog_biomes, animalia.registered_biome_groups["swamp"].biomes)
 | 
			
		||||
    insert_all(frog_biomes, animalia.registered_biome_groups["tropical"].biomes)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:bat", {
 | 
			
		||||
    chance = 2,
 | 
			
		||||
    min_radius = 4,
 | 
			
		||||
    max_radius = 16,
 | 
			
		||||
    min_light = 0,
 | 
			
		||||
    min_height = -512,
 | 
			
		||||
    max_height = 0,
 | 
			
		||||
    min_group = 3,
 | 
			
		||||
    max_group = 5,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["cave"].biomes,
 | 
			
		||||
    spawn_in_nodes = true,
 | 
			
		||||
    nodes = {"air", "ignore"}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:chicken", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 3,
 | 
			
		||||
    max_group = 5,
 | 
			
		||||
    biomes = chicken_biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:cow", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 3,
 | 
			
		||||
    max_group = 4,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["grassland"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:frog", {
 | 
			
		||||
    chance = 2,
 | 
			
		||||
    min_radius = 4,
 | 
			
		||||
    max_radius = 16,
 | 
			
		||||
    min_light = 0,
 | 
			
		||||
    min_height = -32,
 | 
			
		||||
    max_height = 8,
 | 
			
		||||
    min_group = 2,
 | 
			
		||||
    max_group = 6,
 | 
			
		||||
    biomes = frog_biomes,
 | 
			
		||||
    spawn_cluster = true,
 | 
			
		||||
    spawn_in_nodes = true,
 | 
			
		||||
    nodes = {"default:water_source"},
 | 
			
		||||
    send_debug = true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:horse", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 4,
 | 
			
		||||
    max_group = 5,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["grassland"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:pig", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 2,
 | 
			
		||||
    max_group = 4,
 | 
			
		||||
    biomes = pig_biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:reindeer", {
 | 
			
		||||
    chance = 4,
 | 
			
		||||
    min_group = 6,
 | 
			
		||||
    max_group = 12,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["boreal"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:sheep", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 3,
 | 
			
		||||
    max_group = 6,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["grassland"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:turkey", {
 | 
			
		||||
    chance = 2,
 | 
			
		||||
    min_group = 3,
 | 
			
		||||
    max_group = 4,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["boreal"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:wolf", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_group = 2,
 | 
			
		||||
    max_group = 3,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["boreal"].biomes
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:bird", {
 | 
			
		||||
    chance = 4,
 | 
			
		||||
    min_light = 0,
 | 
			
		||||
    min_group = 12,
 | 
			
		||||
    max_group = 16,
 | 
			
		||||
    biomes = animalia.registered_biome_groups["common"].biomes,
 | 
			
		||||
    spawn_cluster = true,
 | 
			
		||||
    spawn_in_nodes = true,
 | 
			
		||||
    nodes = {"air", "ignore"}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:tropical_fish", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_height = -128,
 | 
			
		||||
    max_height = 256,
 | 
			
		||||
    min_group = 8,
 | 
			
		||||
    max_group = 12,
 | 
			
		||||
    spawn_cluster = true,
 | 
			
		||||
    spawn_in_nodes = true,
 | 
			
		||||
    nodes = {"default:water_source"}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
---------------------
 | 
			
		||||
-- Mapgen Spawning --
 | 
			
		||||
---------------------
 | 
			
		||||
 | 
			
		||||
local function vec_raise(v, n)
 | 
			
		||||
    return {x = v.x, y = v.y + n, z = v.z}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function is_value_in_table(tbl, val)
 | 
			
		||||
    for _, v in pairs(tbl) do
 | 
			
		||||
        if v == val then
 | 
			
		||||
            return true
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_biome_name(pos)
 | 
			
		||||
    if not pos then return end
 | 
			
		||||
    return minetest.get_biome_name(minetest.get_biome_data(pos).biome)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function get_ground_level(pos)
 | 
			
		||||
    local node = minetest.get_node(pos)
 | 
			
		||||
    local node_def = minetest.registered_nodes[node.name]
 | 
			
		||||
    local height = 0
 | 
			
		||||
    while node_def.walkable
 | 
			
		||||
    and height < 4 do
 | 
			
		||||
        height = height + 1
 | 
			
		||||
        node = minetest.get_node(vec_raise(pos, height))
 | 
			
		||||
        node_def = minetest.registered_nodes[node.name]
 | 
			
		||||
    end
 | 
			
		||||
    return vec_raise(pos, height)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function dist_to_nearest_player(pos)
 | 
			
		||||
    local dist
 | 
			
		||||
    for _, player in pairs(minetest.get_connected_players()) do
 | 
			
		||||
        local player_pos = player:get_pos()
 | 
			
		||||
        if player_pos
 | 
			
		||||
        and (not dist
 | 
			
		||||
        or dist > vector.distance(pos, player_pos)) then
 | 
			
		||||
            dist = vector.distance(pos, player_pos)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return dist or 100
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function get_spawnable_mobs(pos)
 | 
			
		||||
    local biome = get_biome_name(pos)
 | 
			
		||||
    if not biome then return end
 | 
			
		||||
    local spawnable = {}
 | 
			
		||||
    for k, v in pairs(creatura.registered_mob_spawns) do
 | 
			
		||||
        if (not v.biomes
 | 
			
		||||
        or is_value_in_table(v.biomes, biome))
 | 
			
		||||
        and k:match("^animalia:")
 | 
			
		||||
        and not v.spawn_in_nodes then
 | 
			
		||||
            table.insert(spawnable, k)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return spawnable
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local mapgen_spawning = minetest.settings:get_bool("animalia_mapgen_spawning") or true
 | 
			
		||||
 | 
			
		||||
animalia.chunks_since_last_spawn = 0
 | 
			
		||||
 | 
			
		||||
local chunk_spawn_add_int = tonumber(minetest.settings:get("chunk_spawn_add_int")) or 6
 | 
			
		||||
 | 
			
		||||
animalia.spawn_queue = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_generated(function(minp, maxp)
 | 
			
		||||
    if not mapgen_spawning then return end
 | 
			
		||||
	animalia.chunks_since_last_spawn = animalia.chunks_since_last_spawn + 1
 | 
			
		||||
	local heightmap = minetest.get_mapgen_object("heightmap")
 | 
			
		||||
	if not heightmap then return end
 | 
			
		||||
	local pos = {
 | 
			
		||||
		x = minp.x + math.floor((maxp.x - minp.x) / 2),
 | 
			
		||||
		y = minp.y,
 | 
			
		||||
		z = minp.z + math.floor((maxp.z - minp.z) / 2)
 | 
			
		||||
	}
 | 
			
		||||
	local hm_i = (pos.x - minp.x + 1) + (((pos.z - minp.z)) * 80)
 | 
			
		||||
	pos.y = heightmap[hm_i]
 | 
			
		||||
	if animalia.chunks_since_last_spawn > chunk_spawn_add_int
 | 
			
		||||
	and pos.y > 0 then
 | 
			
		||||
		local heightmap = minetest.get_mapgen_object("heightmap")
 | 
			
		||||
		if not heightmap then return end
 | 
			
		||||
		local center = {
 | 
			
		||||
			x = math.floor(minp.x + ((maxp.x - minp.x) * 0.5) + 0.5),
 | 
			
		||||
			y = minp.y,
 | 
			
		||||
			z = math.floor(minp.z + ((maxp.z - minp.z) * 0.5) + 0.5),
 | 
			
		||||
		}
 | 
			
		||||
		local light = minetest.get_natural_light(center)
 | 
			
		||||
		while center.y < maxp.y
 | 
			
		||||
		and light < 10 do
 | 
			
		||||
			center.y = center.y + 1
 | 
			
		||||
			light = minetest.get_natural_light(center)
 | 
			
		||||
		end
 | 
			
		||||
        local spawnable_mobs = get_spawnable_mobs(center)
 | 
			
		||||
        if spawnable_mobs then
 | 
			
		||||
            local mob = spawnable_mobs[random(#spawnable_mobs)]
 | 
			
		||||
            table.insert(animalia.spawn_queue, {pos = center, mob = mob, group = random(3, 4)})
 | 
			
		||||
            table.insert(animalia.spawn_points, center)
 | 
			
		||||
        end
 | 
			
		||||
		animalia.chunks_since_last_spawn = 0
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local respawn_interval = 15
 | 
			
		||||
 | 
			
		||||
minetest.register_globalstep(function(dtime)
 | 
			
		||||
    respawn_interval = respawn_interval - dtime
 | 
			
		||||
    if respawn_interval <= 0 then
 | 
			
		||||
        if #animalia.spawn_points > 0 then
 | 
			
		||||
            for i = 1, #animalia.spawn_points do
 | 
			
		||||
                local point = animalia.spawn_points[i]
 | 
			
		||||
                if dist_to_nearest_player(point) < 48
 | 
			
		||||
                and minetest.get_node_or_nil(point) then
 | 
			
		||||
                    local spawnable_mobs = get_spawnable_mobs(point)
 | 
			
		||||
                    if spawnable_mobs then
 | 
			
		||||
                        local mob = spawnable_mobs[random(#spawnable_mobs)]
 | 
			
		||||
                        local objects = minetest.get_objects_inside_radius(point, 32)
 | 
			
		||||
                        local spawn = true
 | 
			
		||||
                        if #objects > 0 then
 | 
			
		||||
                            for i = 1, #objects do
 | 
			
		||||
                                local object = objects[i]
 | 
			
		||||
                                if object:get_luaentity()
 | 
			
		||||
                                and object:get_luaentity().name:find("animalia:") then
 | 
			
		||||
                                    spawn = false
 | 
			
		||||
                                    break
 | 
			
		||||
                                end
 | 
			
		||||
                            end
 | 
			
		||||
                        end
 | 
			
		||||
                        if spawn then
 | 
			
		||||
                            table.insert(animalia.spawn_queue, {pos = point, mob = mob, group = random(3, 4)})
 | 
			
		||||
                        end
 | 
			
		||||
                    end
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        respawn_interval = 15
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local chunk_spawn_queue_int  = tonumber(minetest.settings:get("chunk_spawn_queue_int")) or 16
 | 
			
		||||
 | 
			
		||||
local function spawn_queued()
 | 
			
		||||
    if not mapgen_spawning then return end
 | 
			
		||||
	local queue = animalia.spawn_queue
 | 
			
		||||
	if #queue > 0 then
 | 
			
		||||
		for i = #queue, 1, -1 do
 | 
			
		||||
            if queue[i].mob then
 | 
			
		||||
                local pos = queue[i].pos
 | 
			
		||||
                for _ = 1, queue[i].group do
 | 
			
		||||
                    pos = {
 | 
			
		||||
                        x = pos.x + random(-3, 3),
 | 
			
		||||
                        y = pos.y,
 | 
			
		||||
                        z = pos.z + random(-3, 3)
 | 
			
		||||
                    }
 | 
			
		||||
                    pos = get_ground_level(pos)
 | 
			
		||||
                    minetest.add_node(pos, {name = "creatura:spawn_node"})
 | 
			
		||||
                    local meta = minetest.get_meta(pos)
 | 
			
		||||
                    meta:set_string("mob", queue[i].mob)
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
			table.remove(animalia.spawn_queue, i)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	minetest.after(chunk_spawn_queue_int, spawn_queued)
 | 
			
		||||
end
 | 
			
		||||
minetest.after(chunk_spawn_queue_int, spawn_queued)
 | 
			
		||||
							
								
								
									
										20
									
								
								api/storage.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								api/storage.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
local mod_storage = minetest.get_mod_storage()
 | 
			
		||||
 | 
			
		||||
local data = {
 | 
			
		||||
    spawn_points = minetest.deserialize(mod_storage:get_string("spawn_points")) or {},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local function save()
 | 
			
		||||
    mod_storage:set_string("spawn_points", minetest.serialize(data.spawn_points))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_shutdown(save)
 | 
			
		||||
minetest.register_on_leaveplayer(save)
 | 
			
		||||
 | 
			
		||||
local function periodic_save()
 | 
			
		||||
    save()
 | 
			
		||||
    minetest.after(120, periodic_save)
 | 
			
		||||
end
 | 
			
		||||
minetest.after(120, periodic_save)
 | 
			
		||||
 | 
			
		||||
return data
 | 
			
		||||
							
								
								
									
										810
									
								
								craftitems.lua
									
									
									
									
									
								
							
							
						
						
									
										810
									
								
								craftitems.lua
									
									
									
									
									
								
							@ -1,11 +1,380 @@
 | 
			
		||||
----------------
 | 
			
		||||
-- Craftitems --
 | 
			
		||||
----------------
 | 
			
		||||
---- Ver 0.1 ---
 | 
			
		||||
 | 
			
		||||
----------------
 | 
			
		||||
-- Animal Net -- Used to capture and store animals
 | 
			
		||||
----------------
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local function vec_raise(v, n)
 | 
			
		||||
    return {x = v.x, y = v.y + n, z = v.z}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local walkable_nodes = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name in pairs(minetest.registered_nodes) do
 | 
			
		||||
        if name ~= "air" and name ~= "ignore" then
 | 
			
		||||
            if minetest.registered_nodes[name].walkable then
 | 
			
		||||
                table.insert(walkable_nodes, name)
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local function correct_name(str)
 | 
			
		||||
    if str then
 | 
			
		||||
        if str:match(":") then str = str:split(":")[2] end
 | 
			
		||||
        return (string.gsub(" " .. str, "%W%l", string.upper):sub(2):gsub("_", " "))
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function register_egg(name, def)
 | 
			
		||||
 | 
			
		||||
	minetest.register_entity(def.mob .. "_egg_sprite", {
 | 
			
		||||
		hp_max = 1,
 | 
			
		||||
		physical = true,
 | 
			
		||||
		collisionbox = {0, 0, 0, 0, 0, 0},
 | 
			
		||||
		visual = "sprite",
 | 
			
		||||
		visual_size = {x = 0.5, y = 0.5},
 | 
			
		||||
		textures = {"animalia_egg.png"},
 | 
			
		||||
		initial_sprite_basepos = {x = 0, y = 0},
 | 
			
		||||
		is_visible = true,
 | 
			
		||||
		on_step = function(self, dtime)
 | 
			
		||||
			local pos = self.object:get_pos()
 | 
			
		||||
			local objects = minetest.get_objects_inside_radius(pos, 1.5)
 | 
			
		||||
			local cube = minetest.find_nodes_in_area(
 | 
			
		||||
				vector.new(pos.x - 0.5, pos.y - 0.5, pos.z - 0.5),
 | 
			
		||||
				vector.new(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5),
 | 
			
		||||
				walkable_nodes)
 | 
			
		||||
			if #objects >= 2 then
 | 
			
		||||
				if objects[2]:get_armor_groups().fleshy then
 | 
			
		||||
					objects[2]:punch(self.object, 2.0, {full_punch_interval = 0.1, damage_groups = {fleshy = 1}}, nil)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			if #cube >= 1 then
 | 
			
		||||
				minetest.add_particlespawner({
 | 
			
		||||
					amount = 6,
 | 
			
		||||
					time = 0.25,
 | 
			
		||||
					minpos = {x = pos.x - 7/16, y = pos.y - 5/16, z = pos.z - 7/16},
 | 
			
		||||
					maxpos = {x = pos.x + 7/16, y = pos.y - 5/16, z = pos.z + 7/16},
 | 
			
		||||
					minvel = vector.new(-1, 2, -1),
 | 
			
		||||
					maxvel = vector.new(1, 5, 1),
 | 
			
		||||
					minacc = vector.new(0, -9.81, 0),
 | 
			
		||||
					maxacc = vector.new(0, -9.81, 0),
 | 
			
		||||
					collisiondetection = true,
 | 
			
		||||
					texture = "animalia_egg_fragment.png",
 | 
			
		||||
				})
 | 
			
		||||
				if random(1, 3) < 2 then
 | 
			
		||||
					local object = minetest.add_entity(pos, def.mob)
 | 
			
		||||
					local ent = object:get_luaentity()
 | 
			
		||||
					ent.growth_scale = 0.7
 | 
			
		||||
					animalia.initialize_api(ent)
 | 
			
		||||
					animalia.protect_from_despawn(ent)
 | 
			
		||||
					self.object:remove()
 | 
			
		||||
				else
 | 
			
		||||
					self.object:remove()
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	local function mobs_shoot_egg(item, player, pointed_thing)
 | 
			
		||||
		local pos = player:get_pos()
 | 
			
		||||
	
 | 
			
		||||
		minetest.sound_play("default_place_node_hard", {
 | 
			
		||||
			pos = pos,
 | 
			
		||||
			gain = 1.0,
 | 
			
		||||
			max_hear_distance = 5,
 | 
			
		||||
		})
 | 
			
		||||
	
 | 
			
		||||
		local vel = 19
 | 
			
		||||
		local gravity = 9
 | 
			
		||||
	
 | 
			
		||||
		local obj = minetest.add_entity({
 | 
			
		||||
			x = pos.x,
 | 
			
		||||
			y = pos.y +1.5,
 | 
			
		||||
			z = pos.z
 | 
			
		||||
		}, def.mob .. "_egg_sprite")
 | 
			
		||||
	
 | 
			
		||||
		local ent = obj:get_luaentity()
 | 
			
		||||
		local dir = player:get_look_dir()
 | 
			
		||||
	
 | 
			
		||||
		ent.velocity = vel -- needed for api internal timing
 | 
			
		||||
		ent.switch = 1 -- needed so that egg doesn't despawn straight away
 | 
			
		||||
	
 | 
			
		||||
		obj:set_velocity({
 | 
			
		||||
			x = dir.x * vel,
 | 
			
		||||
			y = dir.y * vel,
 | 
			
		||||
			z = dir.z * vel
 | 
			
		||||
		})
 | 
			
		||||
	
 | 
			
		||||
		obj:set_acceleration({
 | 
			
		||||
			x = dir.x * -3,
 | 
			
		||||
			y = -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
 | 
			
		||||
 | 
			
		||||
	minetest.register_craftitem(name, {
 | 
			
		||||
		description = def.description,
 | 
			
		||||
		inventory_image = def.inventory_image .. ".png",
 | 
			
		||||
		on_use = mobs_shoot_egg,
 | 
			
		||||
		groups = {food_egg = 1, flammable = 2},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	minetest.register_craftitem(name .. "_fried", {
 | 
			
		||||
		description = "Fried " .. def.description,
 | 
			
		||||
		inventory_image = def.inventory_image .. "_fried.png",
 | 
			
		||||
		on_use = minetest.item_eat(4),
 | 
			
		||||
		groups = {food_egg = 1, flammable = 2},
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	minetest.register_craft({
 | 
			
		||||
		type  =  "cooking",
 | 
			
		||||
		recipe  = name,
 | 
			
		||||
		output = name .. "_fried",
 | 
			
		||||
	})
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-----------
 | 
			
		||||
-- Drops --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:leather", {
 | 
			
		||||
    description = "Leather",
 | 
			
		||||
    inventory_image = "animalia_leather.png",
 | 
			
		||||
	groups = {flammable = 2, leather = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:feather", {
 | 
			
		||||
	description = "Feather",
 | 
			
		||||
	inventory_image = "animalia_feather.png",
 | 
			
		||||
	groups = {flammable = 2, feather = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-- Meat --
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:beef_raw", {
 | 
			
		||||
	description = "Raw Beef",
 | 
			
		||||
	inventory_image = "animalia_beef_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:beef_cooked", {
 | 
			
		||||
	description = "Steak",
 | 
			
		||||
	inventory_image = "animalia_beef_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(8),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:beef_raw",
 | 
			
		||||
	output = "animalia:beef_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:mutton_raw", {
 | 
			
		||||
	description = "Raw Mutton",
 | 
			
		||||
	inventory_image = "animalia_mutton_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:mutton_cooked", {
 | 
			
		||||
	description = "Cooked Mutton",
 | 
			
		||||
	inventory_image = "animalia_mutton_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(6),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:mutton_raw",
 | 
			
		||||
	output = "animalia:mutton_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:porkchop_raw", {
 | 
			
		||||
	description = "Raw Porkchop",
 | 
			
		||||
	inventory_image = "animalia_porkchop_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:porkchop_cooked", {
 | 
			
		||||
	description = "Cooked Porkchop",
 | 
			
		||||
	inventory_image = "animalia_porkchop_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(7),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:porkchop_raw",
 | 
			
		||||
	output = "animalia:porkchop_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:poultry_raw", {
 | 
			
		||||
	description = "Raw Poultry",
 | 
			
		||||
	inventory_image = "animalia_poultry_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:poultry_cooked", {
 | 
			
		||||
	description = "Cooked Poultry",
 | 
			
		||||
	inventory_image = "animalia_poultry_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(6),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:poultry_raw",
 | 
			
		||||
	output = "animalia:poultry_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
register_egg("animalia:chicken_egg", {
 | 
			
		||||
	description = "Chicken Egg",
 | 
			
		||||
	inventory_image = "animalia_egg",
 | 
			
		||||
	mob = "animalia:chicken"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
----------
 | 
			
		||||
-- Misc --
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:bucket_milk", {
 | 
			
		||||
	description = "Bucket of Milk",
 | 
			
		||||
	inventory_image = "animalia_milk_bucket.png",
 | 
			
		||||
	stack_max = 1,
 | 
			
		||||
	on_use = minetest.item_eat(8, "bucket:bucket_empty"),
 | 
			
		||||
	groups = {food_milk = 1, flammable = 3},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
function grow_crops(pos, nodename)
 | 
			
		||||
    local checkname = nodename:sub(1, string.len(nodename) - 1)
 | 
			
		||||
    if minetest.registered_nodes[checkname .. "1"]
 | 
			
		||||
    and minetest.registered_nodes[checkname .. "2"]
 | 
			
		||||
    and minetest.registered_nodes[checkname .. "2"].drawtype == "plantlike" then -- node is more than likely a plant
 | 
			
		||||
        local stage = tonumber(string.sub(nodename, -1)) or 0
 | 
			
		||||
        local newname = checkname .. (stage + 1)
 | 
			
		||||
        if minetest.registered_nodes[newname] then
 | 
			
		||||
            local def = minetest.registered_nodes[newname]
 | 
			
		||||
            def = def and def.place_param2 or 0
 | 
			
		||||
            minetest.set_node(pos, {name = newname, param2 = def})
 | 
			
		||||
            minetest.add_particlespawner({
 | 
			
		||||
                amount = 6,
 | 
			
		||||
                time = 0.1,
 | 
			
		||||
                minpos = vector.subtract(pos, 0.5),
 | 
			
		||||
                maxpos = vector.add(pos, 0.5),
 | 
			
		||||
                minvel = {
 | 
			
		||||
                    x = -0.5,
 | 
			
		||||
                    y = 0.5,
 | 
			
		||||
                    z = -0.5
 | 
			
		||||
                },
 | 
			
		||||
                maxvel = {
 | 
			
		||||
                    x = 0.5,
 | 
			
		||||
                    y = 1,
 | 
			
		||||
                    z = 0.5
 | 
			
		||||
                },
 | 
			
		||||
                minacc = {
 | 
			
		||||
                    x = 0,
 | 
			
		||||
                    y = 2,
 | 
			
		||||
                    z = 0
 | 
			
		||||
                },
 | 
			
		||||
                maxacc = {
 | 
			
		||||
                    x = 0,
 | 
			
		||||
                    y = 4,
 | 
			
		||||
                    z = 0
 | 
			
		||||
                },
 | 
			
		||||
                minexptime = 0.5,
 | 
			
		||||
                maxexptime = 1,
 | 
			
		||||
                minsize = 1,
 | 
			
		||||
                maxsize = 2,
 | 
			
		||||
                collisiondetection = false,
 | 
			
		||||
                vertical = false,
 | 
			
		||||
                use_texture_alpha = true,
 | 
			
		||||
                texture = "creatura_particle_green.png",
 | 
			
		||||
                glow = 6
 | 
			
		||||
            })
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local guano_fert = minetest.settings:get_bool("guano_fertilization")
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:bucket_guano", {
 | 
			
		||||
	description = "Bucket of Guano",
 | 
			
		||||
	inventory_image = "animalia_guano_bucket.png",
 | 
			
		||||
	stack_max = 1,
 | 
			
		||||
	groups = {flammable = 3},
 | 
			
		||||
	on_place = function(itemstack, placer, pointed_thing)
 | 
			
		||||
        local pos = pointed_thing.above
 | 
			
		||||
        if pos then
 | 
			
		||||
            local under = minetest.get_node(pointed_thing.under)
 | 
			
		||||
            local node = minetest.registered_nodes[under.name]
 | 
			
		||||
            if node and node.on_rightclick then
 | 
			
		||||
                return node.on_rightclick(pointed_thing.under, under, placer,
 | 
			
		||||
                                          itemstack)
 | 
			
		||||
            end
 | 
			
		||||
            if pos
 | 
			
		||||
			and not minetest.is_protected(pos, placer:get_player_name()) then
 | 
			
		||||
				if guano_fert then
 | 
			
		||||
					local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(pos, 5), vector.add(pos, 5), {"group:grass", "group:plant", "group:flora"})
 | 
			
		||||
					if #nodes > 0 then
 | 
			
		||||
						for n = 1, #nodes do
 | 
			
		||||
							grow_crops(nodes[n], minetest.get_node(nodes[n]).name)
 | 
			
		||||
						end
 | 
			
		||||
						local replace = itemstack:get_meta():get_string("original_item")
 | 
			
		||||
						if not replace
 | 
			
		||||
						or replace == "" then
 | 
			
		||||
							replace = "bucket:bucket_empty"
 | 
			
		||||
						end
 | 
			
		||||
						itemstack:set_name(replace)
 | 
			
		||||
					end
 | 
			
		||||
				else
 | 
			
		||||
					minetest.set_node(pos, {name = "animalia:guano"})
 | 
			
		||||
					local replace = itemstack:get_meta():get_string("original_item")
 | 
			
		||||
					if not replace
 | 
			
		||||
					or replace == "" then
 | 
			
		||||
						replace = "bucket:bucket_empty"
 | 
			
		||||
					end
 | 
			
		||||
					itemstack:set_name(replace)
 | 
			
		||||
				end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        return itemstack
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-----------
 | 
			
		||||
-- Tools --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:cat_toy", {
 | 
			
		||||
    description = "Cat Toy",
 | 
			
		||||
    inventory_image = "animalia_cat_toy.png",
 | 
			
		||||
    wield_image = "animalia_cat_toy.png^[transformFYR90",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:saddle", {
 | 
			
		||||
    description = "Saddle",
 | 
			
		||||
    inventory_image = "animalia_saddle.png",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_tool("animalia:shears", {
 | 
			
		||||
	description = "Shears",
 | 
			
		||||
	inventory_image = "animalia_shears.png",
 | 
			
		||||
	groups = {flammable = 2}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:net", {
 | 
			
		||||
    description = "Animal Net",
 | 
			
		||||
@ -18,8 +387,8 @@ minetest.register_craftitem("animalia:net", {
 | 
			
		||||
            if not ent.name:match("^animalia:") or not ent.catch_with_net then
 | 
			
		||||
                return
 | 
			
		||||
            end
 | 
			
		||||
            local ent_name = mob_core.get_name_proper(ent.name)
 | 
			
		||||
            local ent_gender = mob_core.get_name_proper(ent.gender)
 | 
			
		||||
            local ent_name = correct_name(ent.name)
 | 
			
		||||
            local ent_gender = correct_name(ent.gender)
 | 
			
		||||
            local meta = itemstack:get_meta()
 | 
			
		||||
            if not meta:get_string("mob") or meta:get_string("mob") == "" then
 | 
			
		||||
                if placer:get_wielded_item():get_count() > 1 then
 | 
			
		||||
@ -41,12 +410,13 @@ minetest.register_craftitem("animalia:net", {
 | 
			
		||||
                end
 | 
			
		||||
                meta:set_string("description", desc)
 | 
			
		||||
                placer:set_wielded_item(itemstack)
 | 
			
		||||
				animalia.protect_from_despawn(ent)
 | 
			
		||||
                ent.object:remove()
 | 
			
		||||
                return itemstack
 | 
			
		||||
            else
 | 
			
		||||
                minetest.chat_send_player(placer:get_player_name(),
 | 
			
		||||
                                          "This Net already contains a " ..
 | 
			
		||||
                                              mob_core.get_name_proper(
 | 
			
		||||
                                              correct_name(
 | 
			
		||||
                                                  meta:get_string("mob")))
 | 
			
		||||
                return
 | 
			
		||||
            end
 | 
			
		||||
@ -80,267 +450,237 @@ minetest.register_craftitem("animalia:net", {
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:net",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"farming:string", "", "farming:string"},
 | 
			
		||||
        {"farming:string", "", "farming:string"},
 | 
			
		||||
        {"group:stick", "farming:string", ""}
 | 
			
		||||
    }
 | 
			
		||||
-----------
 | 
			
		||||
-- Nodes --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
minetest.register_node("animalia:guano", {
 | 
			
		||||
	description = "Guano",
 | 
			
		||||
	tiles = {"animalia_guano.png"},
 | 
			
		||||
	paramtype = "light",
 | 
			
		||||
	buildable_to = true,
 | 
			
		||||
	floodable = true,
 | 
			
		||||
	walkable = false,
 | 
			
		||||
	drawtype = "nodebox",
 | 
			
		||||
	node_box = {
 | 
			
		||||
		type = "fixed",
 | 
			
		||||
		fixed = {
 | 
			
		||||
			{-0.5, -0.5, -0.5, 0.5, -0.25, 0.5},
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	groups = {crumbly = 3, falling_node = 1},
 | 
			
		||||
	on_punch = function(pos, _, player)
 | 
			
		||||
		local item = player:get_wielded_item()
 | 
			
		||||
		local item_name = player:get_wielded_item():get_name()
 | 
			
		||||
		if item_name:find("bucket")
 | 
			
		||||
		and item_name:find("empty") then
 | 
			
		||||
			local stack = ItemStack("animalia:bucket_guano")
 | 
			
		||||
			stack:get_meta():set_string("original_item", item_name)
 | 
			
		||||
			player:set_wielded_item(stack)
 | 
			
		||||
			minetest.remove_node(pos)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-----------
 | 
			
		||||
-- Lasso -- Used to pull animals around, and can be attached to fences
 | 
			
		||||
-- Libri --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
local function is_lasso_in_use(player)
 | 
			
		||||
    for _, ent in pairs(minetest.luaentities) do
 | 
			
		||||
        if ent.name
 | 
			
		||||
        and ent.name:match("^animalia:") then
 | 
			
		||||
            if ent.lasso_player
 | 
			
		||||
            and ent.lasso_player == player then
 | 
			
		||||
                return true
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return false
 | 
			
		||||
animalia.libri_pages = {}
 | 
			
		||||
 | 
			
		||||
function animalia.show_libri_main_form(player, pages, group)
 | 
			
		||||
	group = group or 1
 | 
			
		||||
    local basic_form = table.concat({
 | 
			
		||||
        "formspec_version[3]",
 | 
			
		||||
        "size[16,10]",
 | 
			
		||||
        "background[-0.7,-0.5;17.5,11.5;animalia_libri_bg_v2.png]"
 | 
			
		||||
	}, "")
 | 
			
		||||
	if group == 1 then
 | 
			
		||||
		if pages[1] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,1.5;4,1;".. pages[1].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[2] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,3.5;4,1;".. pages[2].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[3] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,5.5;4,1;".. pages[3].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[4] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,7.5;4,1;".. pages[4].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[5] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,1.5;4,1;".. pages[5].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[6] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,3.5;4,1;".. pages[6].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[7] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,5.5;4,1;".. pages[7].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[8] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,7.5;4,1;".. pages[8].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[9] then
 | 
			
		||||
			basic_form = basic_form .. "button[12.25,9;1.5,1;btn_next;Next Page]"
 | 
			
		||||
		end
 | 
			
		||||
	elseif group == 2 then
 | 
			
		||||
		if pages[9] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,1.5;4,1;".. pages[9].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[10] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,3.5;4,1;".. pages[10].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[11] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,5.5;4,1;".. pages[11].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[12] then
 | 
			
		||||
			basic_form = basic_form .. "button[1.75,7.5;4,1;".. pages[12].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[13] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,1.5;4,1;".. pages[13].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[14] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,3.5;4,1;".. pages[14].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[15] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,5.5;4,1;".. pages[15].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
		if pages[16] then
 | 
			
		||||
			basic_form = basic_form .. "button[10.25,7.5;4,1;".. pages[16].form .."]"
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	animalia.libri_pages[player:get_player_name()] = pages
 | 
			
		||||
    minetest.show_formspec(player:get_player_name(), "animalia:libri_main", basic_form)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:lasso_visual", {
 | 
			
		||||
    hp_max = 1,
 | 
			
		||||
    armor_groups = {immortal = 1},
 | 
			
		||||
    physical = false,
 | 
			
		||||
    collisionbox = {0, 0, 0, 0, 0, 0},
 | 
			
		||||
    visual = "mesh",
 | 
			
		||||
    mesh = "animalia_lasso.b3d",
 | 
			
		||||
    visual_size = {x = 2, y = 2},
 | 
			
		||||
    textures = {"animalia_lasso_cube.png"},
 | 
			
		||||
    is_visible = true,
 | 
			
		||||
    makes_footstep_sound = false,
 | 
			
		||||
    glow = 1,
 | 
			
		||||
    on_step = function(self, dtime)
 | 
			
		||||
        self.object:set_armor_groups({immortal = 1})
 | 
			
		||||
        if not self.parent
 | 
			
		||||
        or not self.anchor_pos
 | 
			
		||||
        or (self.parent
 | 
			
		||||
        and (not mobkit.is_alive(self.parent)
 | 
			
		||||
        or not self.parent:get_luaentity().caught_with_lasso)) then
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        local pos = mobkit.get_stand_pos(self.parent)
 | 
			
		||||
        pos.y = pos.y + (self.parent:get_luaentity().height * 0.5)
 | 
			
		||||
        self.object:set_pos(self.anchor_pos)
 | 
			
		||||
        local rot = vector.dir_to_rotation(vector.direction(self.anchor_pos, pos))
 | 
			
		||||
        self.object:set_rotation(rot)
 | 
			
		||||
        self.object:set_properties({
 | 
			
		||||
            visual_size = {x = 6, z = 10 * vector.distance(self.anchor_pos, pos), y = 6}
 | 
			
		||||
        })
 | 
			
		||||
    end
 | 
			
		||||
minetest.register_craftitem("animalia:libri_animalia", {
 | 
			
		||||
	description = "Libri Animalia",
 | 
			
		||||
	inventory_image = "animalia_libri_animalia.png",
 | 
			
		||||
	stack_max = 1,
 | 
			
		||||
	on_place = function(itemstack, player, pointed_thing)
 | 
			
		||||
		if pointed_thing and pointed_thing.type == "object" then return end
 | 
			
		||||
		local meta = itemstack:get_meta()
 | 
			
		||||
		local pages = minetest.deserialize(meta:get_string("pages"))
 | 
			
		||||
        local desc = meta:get_string("description")
 | 
			
		||||
		if not pages
 | 
			
		||||
		or #pages < 1 then return end
 | 
			
		||||
		animalia.show_libri_main_form(player, pages)
 | 
			
		||||
	end,
 | 
			
		||||
	on_secondary_use = function(itemstack, player, pointed_thing)
 | 
			
		||||
		if pointed_thing and pointed_thing.type == "object" then return end
 | 
			
		||||
		local meta = itemstack:get_meta()
 | 
			
		||||
		local pages = minetest.deserialize(meta:get_string("pages"))
 | 
			
		||||
        local desc = meta:get_string("description")
 | 
			
		||||
		if not pages
 | 
			
		||||
		or #pages < 1 then return end
 | 
			
		||||
		animalia.show_libri_main_form(player, pages)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:lasso_fence_ent", {
 | 
			
		||||
    hp_max = 1,
 | 
			
		||||
    physical = false,
 | 
			
		||||
    collisionbox = {-0.25,-0.25,-0.25, 0.25,0.25,0.25},
 | 
			
		||||
    visual = "cube",
 | 
			
		||||
    visual_size = {x = 0.3, y = 0.3},
 | 
			
		||||
    mesh = "model",
 | 
			
		||||
    textures = {
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
        "animalia_lasso_cube.png",
 | 
			
		||||
    },
 | 
			
		||||
    makes_footstep_sound = false,
 | 
			
		||||
    on_step = function(self)
 | 
			
		||||
        if not self.parent
 | 
			
		||||
        or not self.parent:get_luaentity()
 | 
			
		||||
        or not self.parent:get_luaentity().lasso_pos then
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        local node = minetest.get_node(pos)
 | 
			
		||||
        if not minetest.registered_nodes[node.name].walkable
 | 
			
		||||
        or minetest.get_item_group(node.name, "fence") < 1 then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_pos = mobkit.remember(ent, "lasso_pos", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
            minetest.add_item(self.object:get_pos(), "animalia:lasso")
 | 
			
		||||
            self.object:remove()
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
    end,
 | 
			
		||||
    on_rightclick = function(self)
 | 
			
		||||
        if self.parent then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_pos = mobkit.remember(ent, "lasso_pos", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        local dirs = {
 | 
			
		||||
            vector.new(1, 0, 0),
 | 
			
		||||
            vector.new(-1, 0, 0),
 | 
			
		||||
            vector.new(0, 1, 0),
 | 
			
		||||
            vector.new(0, -1, 0),
 | 
			
		||||
            vector.new(0, 0, 1),
 | 
			
		||||
            vector.new(0, 0, -1),
 | 
			
		||||
        }
 | 
			
		||||
        for i = 1, 6 do
 | 
			
		||||
            local pos = vector.add(self.object:get_pos(), dirs[i])
 | 
			
		||||
            local name = minetest.get_node(pos).name
 | 
			
		||||
            if not minetest.registered_nodes[name].walkable then
 | 
			
		||||
                minetest.add_item(pos, "animalia:lasso")
 | 
			
		||||
                break
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        self.object:remove()
 | 
			
		||||
    end,
 | 
			
		||||
    on_punch = function(self)
 | 
			
		||||
        if self.parent then
 | 
			
		||||
            local ent = self.parent:get_luaentity()
 | 
			
		||||
            ent.lasso_pos = mobkit.remember(ent, "lasso_pos", nil)
 | 
			
		||||
            ent.caught_with_lasso = nil
 | 
			
		||||
            if ent.lasso_visual then
 | 
			
		||||
                ent.lasso_visual:remove()
 | 
			
		||||
                ent.lasso_visual = nil
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        local dirs = {
 | 
			
		||||
            vector.new(1, 0, 0),
 | 
			
		||||
            vector.new(-1, 0, 0),
 | 
			
		||||
            vector.new(0, 1, 0),
 | 
			
		||||
            vector.new(0, -1, 0),
 | 
			
		||||
            vector.new(0, 0, 1),
 | 
			
		||||
            vector.new(0, 0, -1),
 | 
			
		||||
        }
 | 
			
		||||
        for i = 1, 6 do
 | 
			
		||||
            local pos = vector.add(self.object:get_pos(), dirs[i])
 | 
			
		||||
            local name = minetest.get_node(pos).name
 | 
			
		||||
            if not minetest.registered_nodes[name].walkable then
 | 
			
		||||
                minetest.add_item(pos, "animalia:lasso")
 | 
			
		||||
                break
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        self.object:remove()
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
--------------
 | 
			
		||||
-- Crafting --
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:lasso", {
 | 
			
		||||
    description = "Lasso",
 | 
			
		||||
    inventory_image = "animalia_lasso.png",
 | 
			
		||||
    on_secondary_use = function(itemstack, placer, pointed_thing)
 | 
			
		||||
        if pointed_thing.type == "object" then
 | 
			
		||||
            if pointed_thing.ref:is_player() then return end
 | 
			
		||||
            local ent = pointed_thing.ref:get_luaentity()
 | 
			
		||||
            if not ent.name:match("^animalia:") or not ent.catch_with_net then
 | 
			
		||||
                return
 | 
			
		||||
            end
 | 
			
		||||
            if not ent.caught_with_lasso
 | 
			
		||||
            and not is_lasso_in_use(placer) then
 | 
			
		||||
                ent.caught_with_lasso = true
 | 
			
		||||
                ent.lasso_player = placer
 | 
			
		||||
            elseif ent.lasso_player
 | 
			
		||||
            and ent.lasso_player == placer then
 | 
			
		||||
                ent.caught_with_lasso = nil
 | 
			
		||||
                ent.lasso_player = nil
 | 
			
		||||
            end
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if string.find(name, "ingot")
 | 
			
		||||
		and string.find(name, "steel") then
 | 
			
		||||
            if not def.groups then
 | 
			
		||||
				def.groups = {}
 | 
			
		||||
			end
 | 
			
		||||
			def.groups["steel_ingot"] = 1
 | 
			
		||||
			minetest.register_item(":" .. name, def)
 | 
			
		||||
        elseif string.find(name, "string") then
 | 
			
		||||
            if not def.groups then
 | 
			
		||||
				def.groups = {}
 | 
			
		||||
			end
 | 
			
		||||
			def.groups["string"] = 1
 | 
			
		||||
			minetest.register_item(":" .. name, def)
 | 
			
		||||
        end
 | 
			
		||||
    end,
 | 
			
		||||
    on_place = function(itemstack, placer, pointed_thing)
 | 
			
		||||
        if pointed_thing.type == "node" then
 | 
			
		||||
            local pos = minetest.get_pointed_thing_position(pointed_thing)
 | 
			
		||||
            if minetest.get_item_group(minetest.get_node(pos).name, "fence") > 0 then
 | 
			
		||||
                local objects = minetest.get_objects_inside_radius(placer:get_pos(), 21)
 | 
			
		||||
                for _, obj in ipairs(objects) do
 | 
			
		||||
                    if obj:get_luaentity()
 | 
			
		||||
                    and obj:get_luaentity().lasso_player
 | 
			
		||||
                    and obj:get_luaentity().lasso_player == placer then
 | 
			
		||||
                        obj:get_luaentity().lasso_pos = pos
 | 
			
		||||
                        obj:get_luaentity().lasso_player = nil
 | 
			
		||||
                        local object = minetest.add_entity(pos, "animalia:lasso_fence_ent")
 | 
			
		||||
                        object:get_luaentity().parent = obj
 | 
			
		||||
                        itemstack:take_item(1)
 | 
			
		||||
                        break
 | 
			
		||||
                    end
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        return itemstack
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:cat_toy",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "", "group:string"},
 | 
			
		||||
        {"", "group:stick", "group:string"},
 | 
			
		||||
        {"group:stick", "", "group:feather"}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:lasso",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "farming:string", "farming:string"},
 | 
			
		||||
        {"", "animalia:leather", "farming:string"},
 | 
			
		||||
        {"farming:string", "", ""}
 | 
			
		||||
        {"", "group:string", "group:string"},
 | 
			
		||||
        {"", "group:leather", "group:string"},
 | 
			
		||||
        {"group:string", "", ""}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-------------
 | 
			
		||||
-- Cat Toy -- Used to quickly increase trust with Cats
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:cat_toy", {
 | 
			
		||||
    description = "Cat Toy",
 | 
			
		||||
    inventory_image = "animalia_cat_toy.png",
 | 
			
		||||
    wield_image = "animalia_cat_toy.png^[transformFYR90",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:cat_toy",
 | 
			
		||||
    output = "animalia:net",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "", "farming:string"},
 | 
			
		||||
        {"", "group:stick", "farming:string"},
 | 
			
		||||
        {"group:stick", "", "group:feather"}
 | 
			
		||||
        {"group:string", "", "group:string"},
 | 
			
		||||
        {"group:string", "", "group:string"},
 | 
			
		||||
        {"group:stick", "group:string", ""}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
------------
 | 
			
		||||
-- Saddle -- Can be attached to a tamed Horse to make it ridable
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:saddle", {
 | 
			
		||||
    description = "Saddle",
 | 
			
		||||
    inventory_image = "animalia_saddle.png",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:saddle",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"animalia:leather", "animalia:leather", "animalia:leather"},
 | 
			
		||||
        {"animalia:leather", "default:steel_ingot", "animalia:leather"},
 | 
			
		||||
        {"farming:string", "", "farming:string"}
 | 
			
		||||
        {"group:leather", "group:leather", "group:leather"},
 | 
			
		||||
        {"group:leather", "group:steel_ingot", "group:leather"},
 | 
			
		||||
        {"group:string", "", "group:string"}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
------------
 | 
			
		||||
-- Shears -- Used to shear Sheep
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
minetest.register_tool("animalia:shears", {
 | 
			
		||||
	description = "Shears",
 | 
			
		||||
	inventory_image = "animalia_shears.png",
 | 
			
		||||
	groups = {flammable = 2}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "animalia:shears",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"", "default:steel_ingot", ""},
 | 
			
		||||
		{"", "animalia:leather", "default:steel_ingot"}
 | 
			
		||||
		{"", "group:steel_ingot", ""},
 | 
			
		||||
		{"", "group:leather", "group:steel_ingot"}
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:libri_animalia",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "", ""},
 | 
			
		||||
        {"animalia:feather", "", ""},
 | 
			
		||||
        {"group:book", "group:color_green", ""}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:libri_animalia",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "", ""},
 | 
			
		||||
        {"animalia:feather", "", ""},
 | 
			
		||||
        {"group:book", "group:unicolor_green", ""}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
    output = "animalia:libri_animalia 2",
 | 
			
		||||
    recipe = {
 | 
			
		||||
        {"", "", ""},
 | 
			
		||||
        {"animalia:libri_animalia", "group:book", ""},
 | 
			
		||||
        {"", "", ""}
 | 
			
		||||
    }
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_on_craft(function(itemstack, player, old_craft_grid)
 | 
			
		||||
	if itemstack:get_name() == "animalia:libri_animalia"
 | 
			
		||||
	and itemstack:get_count() > 1 then
 | 
			
		||||
		for _, old_libri in pairs(old_craft_grid) do
 | 
			
		||||
			if old_libri:get_meta():get_string("pages") then
 | 
			
		||||
				local pages = old_libri:get_meta():get_string("pages")
 | 
			
		||||
				itemstack:get_meta():set_string("pages", pages)
 | 
			
		||||
				return itemstack
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
							
								
								
									
										201
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										201
									
								
								init.lua
									
									
									
									
									
								
							@ -1,150 +1,83 @@
 | 
			
		||||
animalia = {}
 | 
			
		||||
better_fauna = animalia
 | 
			
		||||
 | 
			
		||||
animalia.mobkit_mobs = {}
 | 
			
		||||
animalia.walkable_nodes = {}
 | 
			
		||||
animalia.spawn_interval = tonumber(minetest.settings:get("animalia_spawn_int")) or 60
 | 
			
		||||
animalia.mobs = {}
 | 
			
		||||
animalia.pets = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
	for name in pairs(minetest.registered_entities) do
 | 
			
		||||
        local mob = minetest.registered_entities[name]
 | 
			
		||||
        if mob.logic or mob.brainfunc then
 | 
			
		||||
            table.insert(animalia.mobkit_mobs, name)
 | 
			
		||||
        end
 | 
			
		||||
	end
 | 
			
		||||
	for name in pairs(minetest.registered_nodes) do
 | 
			
		||||
		if name ~= "air" and name ~= "ignore" then
 | 
			
		||||
			if minetest.registered_nodes[name].walkable then
 | 
			
		||||
				table.insert(animalia.walkable_nodes, name)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
minetest.register_on_joinplayer(function(player)
 | 
			
		||||
    local name = player:get_player_name()
 | 
			
		||||
    animalia.pets[name] = {}
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
animalia.frame_blend = 0
 | 
			
		||||
 | 
			
		||||
if minetest.has_feature("object_step_has_moveresult") then
 | 
			
		||||
	animalia.frame_blend = 0.3
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local fancy_step = minetest.settings:get_bool("animalia_fancy_step")
 | 
			
		||||
 | 
			
		||||
local stepheight = 1.1
 | 
			
		||||
 | 
			
		||||
if fancy_step then
 | 
			
		||||
	stepheight = 0.1
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.register_mob(name, def)
 | 
			
		||||
	minetest.register_entity("animalia:".. name, {
 | 
			
		||||
		physical = true,
 | 
			
		||||
		collide_with_objects = true,
 | 
			
		||||
		visual = "mesh",
 | 
			
		||||
		makes_footstep_sound = true,
 | 
			
		||||
		static_save = true,
 | 
			
		||||
		timeout = 0,
 | 
			
		||||
		-- Stats
 | 
			
		||||
		max_hp = def.health or 20,
 | 
			
		||||
		armor_groups = {fleshy = def.fleshy},
 | 
			
		||||
		view_range = def.view_range or 32,
 | 
			
		||||
		lung_capacity = def.lung_capacity or 10,
 | 
			
		||||
		-- Visual
 | 
			
		||||
		collisionbox = def.collisionbox,
 | 
			
		||||
		visual_size = def.visual_size,
 | 
			
		||||
		mesh = def.mesh,
 | 
			
		||||
		textures = def.textures or nil,
 | 
			
		||||
		scale_stage1 = def.scale_stage1 or 0.75,
 | 
			
		||||
		scale_stage2 = def.scale_stage2 or 0.85,
 | 
			
		||||
		scale_stage3 = def.scale_stage3 or 0.95,
 | 
			
		||||
		female_textures = def.female_textures or nil,
 | 
			
		||||
		male_textures = def.male_textures or nil,
 | 
			
		||||
		child_textures = def.child_textures or nil,
 | 
			
		||||
		animation = def.animations,
 | 
			
		||||
		-- Physics
 | 
			
		||||
		ignore_liquidflag = false,
 | 
			
		||||
		push_on_collide = true,
 | 
			
		||||
		buoyancy = def.buoyancy or 0.25,
 | 
			
		||||
		max_speed = def.speed,
 | 
			
		||||
		jump_height = def.jump_height or 1.1,
 | 
			
		||||
		stepheight = stepheight,
 | 
			
		||||
		max_fall = def.max_fall or 2,
 | 
			
		||||
		-- Attributes
 | 
			
		||||
		sounds = def.sounds,
 | 
			
		||||
		obstacle_avoidance_range = def.obstacle_avoidance_range or nil,
 | 
			
		||||
		surface_avoidance_range = def.surface_avoidance_range or nil,
 | 
			
		||||
		floor_avoidance_range = def.floor_avoidance_range or nil,
 | 
			
		||||
		fall_damage = def.fall_damage or true,
 | 
			
		||||
		igniter_damage = def.igniter_damage or 2,
 | 
			
		||||
		reach = def.reach or 2,
 | 
			
		||||
		damage = def.damage or 2,
 | 
			
		||||
		knockback = def.knockback or 4,
 | 
			
		||||
		punch_cooldown = def.punch_cooldown or 1,
 | 
			
		||||
		core_growth = def.growth or true,
 | 
			
		||||
		catch_with_net = def.catch_with_net or true,
 | 
			
		||||
		driver_scale = def.driver_scale or nil,
 | 
			
		||||
		player_rotation = def.player_rotation or nil,
 | 
			
		||||
		driver_attach_at = def.driver_attach_at or nil,
 | 
			
		||||
		driver_attach_bone = def.driver_attach_bone or nil,
 | 
			
		||||
		driver_eye_offset = def.driver_eye_offset or nil,
 | 
			
		||||
		-- Behavior
 | 
			
		||||
		defend_owner = def.defend_owner,
 | 
			
		||||
		follow = def.follow,
 | 
			
		||||
		consumable_nodes = def.consumable_nodes or nil,
 | 
			
		||||
		drops = def.drops,
 | 
			
		||||
		-- Functions
 | 
			
		||||
		head_data = def.head_data or nil,
 | 
			
		||||
		register_targets = def.register_targets or nil,
 | 
			
		||||
		physics = def.physics or nil,
 | 
			
		||||
		logic = def.logic,
 | 
			
		||||
		get_staticdata = mobkit.statfunc,
 | 
			
		||||
		on_step = def.on_step,
 | 
			
		||||
		on_activate = def.on_activate,
 | 
			
		||||
		on_rightclick = def.on_rightclick,
 | 
			
		||||
		on_punch = def.on_punch,
 | 
			
		||||
	})
 | 
			
		||||
	table.insert(animalia.mobs, "animalia:" .. name)
 | 
			
		||||
end
 | 
			
		||||
minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
    local name = player:get_player_name()
 | 
			
		||||
    animalia.pets[name] = nil
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local path = minetest.get_modpath("animalia")
 | 
			
		||||
 | 
			
		||||
local spawn_mobs = minetest.settings:get_bool("spawn_mobs") or true
 | 
			
		||||
 | 
			
		||||
dofile(path.."/api/api.lua")
 | 
			
		||||
if spawn_mobs then
 | 
			
		||||
	dofile(path.."/api/spawn.lua")
 | 
			
		||||
end
 | 
			
		||||
dofile(path.."/api/behaviors.lua")
 | 
			
		||||
dofile(path.."/api/lasso.lua")
 | 
			
		||||
dofile(path.."/craftitems.lua")
 | 
			
		||||
dofile(path.."/mobs/cat.lua")
 | 
			
		||||
dofile(path.."/mobs/chicken.lua")
 | 
			
		||||
dofile(path.."/mobs/cow.lua")
 | 
			
		||||
dofile(path.."/mobs/horse.lua")
 | 
			
		||||
dofile(path.."/mobs/pig.lua")
 | 
			
		||||
dofile(path.."/mobs/reindeer.lua")
 | 
			
		||||
dofile(path.."/mobs/sheep.lua")
 | 
			
		||||
dofile(path.."/mobs/turkey.lua")
 | 
			
		||||
dofile(path.."/mobs/wolf.lua")
 | 
			
		||||
dofile(path.."/api/legacy_convert.lua")
 | 
			
		||||
 | 
			
		||||
local convert_redo_items = minetest.settings:get_bool("convert_redo_items") or false
 | 
			
		||||
animalia.animals = {
 | 
			
		||||
    "animalia:bat",
 | 
			
		||||
    "animalia:bird",
 | 
			
		||||
    "animalia:cat",
 | 
			
		||||
    "animalia:chicken",
 | 
			
		||||
    "animalia:cow",
 | 
			
		||||
    "animalia:tropical_fish",
 | 
			
		||||
    "animalia:frog",
 | 
			
		||||
    "animalia:horse",
 | 
			
		||||
    "animalia:pig",
 | 
			
		||||
    "animalia:reindeer",
 | 
			
		||||
    "animalia:sheep",
 | 
			
		||||
    "animalia:turkey",
 | 
			
		||||
    "animalia:wolf",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if convert_redo_items then
 | 
			
		||||
	minetest.register_alias_force("mobs:lasso","animalia:lasso")
 | 
			
		||||
	minetest.register_alias_force("mobs:saddle","animalia:saddle")
 | 
			
		||||
	minetest.register_alias_force("mobs:shears","animalia:shears")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:chicken_raw","animalia:poultry_raw")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:chicken_feather","animalia:feather")
 | 
			
		||||
	minetest.register_alias_force("mobs:meat_raw" ,"animalia:beef_raw")
 | 
			
		||||
	minetest.register_alias_force("mobs:meat","animalia:beef_cooked")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:mutton_raw","animalia:mutton_raw")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:mutton_cooked","animalia:mutton_cooked")
 | 
			
		||||
	minetest.register_alias_force("mobs:leather" ,"animalia:leather")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:egg","animalia:chicken_egg")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:chicken_egg_fried" ,"animalia:chicken_egg_fried")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:milk_bucket","animalia:bucket_milk")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:chicken_cooked" ,"animalia:poultry_cooked")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:pork_raw" ,"animalia:porkchop_raw")
 | 
			
		||||
	minetest.register_alias_force("mobs_animal:pork_cooked","animalia:porkchop_cooked")
 | 
			
		||||
for i = 1, #animalia.animals do
 | 
			
		||||
    local name = string.split(animalia.animals[i], ":")[2]
 | 
			
		||||
    dofile(path.."/mobs/" .. name .. ".lua")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.log("action", "[MOD] Animalia [0.2] loaded")
 | 
			
		||||
if minetest.settings:get_bool("spawn_mobs", true) then
 | 
			
		||||
    dofile(path.."/api/spawning.lua")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_entities) do
 | 
			
		||||
        if def.logic
 | 
			
		||||
        or def.brainfunc
 | 
			
		||||
        or def.bh_tree
 | 
			
		||||
        or def._cmi_is_mob then
 | 
			
		||||
            local old_punch = def.on_punch
 | 
			
		||||
            if not old_punch then
 | 
			
		||||
                old_punch = function() end
 | 
			
		||||
            end
 | 
			
		||||
            local on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir)
 | 
			
		||||
                old_punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
 | 
			
		||||
                local pos = self.object:get_pos()
 | 
			
		||||
                if not pos then
 | 
			
		||||
                    return
 | 
			
		||||
                end
 | 
			
		||||
                if puncher:is_player()
 | 
			
		||||
                and animalia.pets[puncher:get_player_name()] then
 | 
			
		||||
                    local pets = animalia.pets[puncher:get_player_name()]
 | 
			
		||||
                    if #pets < 1 then return end
 | 
			
		||||
                    for i = 1, #pets do
 | 
			
		||||
                        local ent = pets[i]:get_luaentity()
 | 
			
		||||
                        if ent.assist_owner then
 | 
			
		||||
                            ent.owner_target = self
 | 
			
		||||
                        end
 | 
			
		||||
                    end
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
            def.on_punch = on_punch
 | 
			
		||||
            minetest.register_entity(":" .. name, def)
 | 
			
		||||
        end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.log("action", "[MOD] Animalia [0.3] loaded")
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										274
									
								
								mobs/bat.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										274
									
								
								mobs/bat.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,274 @@
 | 
			
		||||
---------
 | 
			
		||||
-- Bat --
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local function get_ceiling_positions(pos, range)
 | 
			
		||||
    local walkable = minetest.find_nodes_in_area(
 | 
			
		||||
        {x = pos.x + range, y = pos.y + range, z = pos.z + range},
 | 
			
		||||
        {x = pos.x - range, y = pos.y, z = pos.z - range},
 | 
			
		||||
        animalia.walkable_nodes
 | 
			
		||||
    )
 | 
			
		||||
    if #walkable < 1 then return {} end
 | 
			
		||||
    local output = {}
 | 
			
		||||
    for i = 1, #walkable do
 | 
			
		||||
        local i_pos = walkable[i]
 | 
			
		||||
        local under = {
 | 
			
		||||
            x = i_pos.x,
 | 
			
		||||
            y = i_pos.y - 1,
 | 
			
		||||
            z = i_pos.z
 | 
			
		||||
        }
 | 
			
		||||
        if minetest.get_node(under).name == "air"
 | 
			
		||||
        and minetest.registered_nodes[minetest.get_node(i_pos).name].walkable then
 | 
			
		||||
            table.insert(output, i_pos)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return output
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local guano_accumulation = minetest.settings:get_bool("guano_accumulation")
 | 
			
		||||
 | 
			
		||||
-- Math --
 | 
			
		||||
 | 
			
		||||
local function clamp(val, min, max)
 | 
			
		||||
	if val < min then
 | 
			
		||||
		val = min
 | 
			
		||||
	elseif max < val then
 | 
			
		||||
		val = max
 | 
			
		||||
	end
 | 
			
		||||
	return val
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
local floor = math.floor
 | 
			
		||||
 | 
			
		||||
-- Vector Math --
 | 
			
		||||
 | 
			
		||||
local vec_dist = vector.distance
 | 
			
		||||
local vec_add = vector.add
 | 
			
		||||
 | 
			
		||||
local function vec_raise(v, n)
 | 
			
		||||
    return {x = v.x, y = v.y + n, z = v.z}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function is_node_walkable(name)
 | 
			
		||||
    local def = minetest.registered_nodes[name]
 | 
			
		||||
    return def and def.walkable
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
creatura.register_mob("animalia:bat", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 5,
 | 
			
		||||
    armor_groups = {fleshy = 200},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 4,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 2500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 100,
 | 
			
		||||
	turn_rate = 12,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_bat.b3d",
 | 
			
		||||
    hitbox = {
 | 
			
		||||
		width = 0.15,
 | 
			
		||||
		height = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_bat_1.png",
 | 
			
		||||
		"animalia_bat_2.png",
 | 
			
		||||
		"animalia_bat_3.png"
 | 
			
		||||
	},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 50, y = 90}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
        fly = {range = {x = 100, y = 140}, speed = 80, frame_blend = 0.3, loop = true},
 | 
			
		||||
        latch = {range = {x = 150, y = 150}, speed = 1, frame_blend = 0, loop = false}
 | 
			
		||||
	},
 | 
			
		||||
    -- Misc
 | 
			
		||||
	sounds = {
 | 
			
		||||
		random = {
 | 
			
		||||
            name = "animalia_bat",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
            distance = 16,
 | 
			
		||||
			variations = 2
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
    follow = {
 | 
			
		||||
		"butterflies:butterfly_red",
 | 
			
		||||
		"butterflies:butterfly_white",
 | 
			
		||||
		"butterflies:butterfly_violet"
 | 
			
		||||
	},
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.is_landed then
 | 
			
		||||
					return 0.1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:aerial_swarm",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self:get_utility() == "animalia:return_to_home"
 | 
			
		||||
				or self:get_utility() == "animalia:wander" then
 | 
			
		||||
					local pos = self.object:get_pos()
 | 
			
		||||
					local player = creatura.get_nearby_player(self)
 | 
			
		||||
					if player
 | 
			
		||||
					and not player:get_player_control().sneak then
 | 
			
		||||
						local dist = vector.distance(pos, player:get_pos())
 | 
			
		||||
						self._nearby_player = player
 | 
			
		||||
						self.is_landed = false
 | 
			
		||||
						return (12 - dist) * 0.1, {self, 1}
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				if self.in_liquid
 | 
			
		||||
				or not self.is_landed then
 | 
			
		||||
					return 0.11, {self, 1}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.is_landed
 | 
			
		||||
				and not self.touching_ground then
 | 
			
		||||
					return 0.12, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:return_to_home",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.home_position then return 0 end
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player then
 | 
			
		||||
					local pos = self.object:get_pos()
 | 
			
		||||
					local dist = vector.distance(pos, player:get_pos())
 | 
			
		||||
					if dist < 9 then
 | 
			
		||||
						return 0
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				local time = (minetest.get_timeofday() * 24000) or 0
 | 
			
		||||
				local is_day = time < 19500 and time > 4500
 | 
			
		||||
				if is_day then
 | 
			
		||||
					return 0.6, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:find_home",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.home_position then return 0 end
 | 
			
		||||
				local pos = self.object:get_pos()
 | 
			
		||||
				local range = self.tracking_range
 | 
			
		||||
				local ceiling = get_ceiling_positions(pos, range / 2)
 | 
			
		||||
				if not ceiling[1] then return 0 end
 | 
			
		||||
				return 1, {self}
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
		self.trust = self:recall("trust") or {}
 | 
			
		||||
		self.home_position = self:recall("home_position") or nil
 | 
			
		||||
		self.is_landed = self:recall("is_landed") or false
 | 
			
		||||
		self.stamina = self:recall("stamina") or 30
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		--animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
		if self.stamina > 0 then
 | 
			
		||||
			if not self.is_landed then
 | 
			
		||||
				self.stamina = self:memorize("stamina", self.stamina - self.dtime)
 | 
			
		||||
			else
 | 
			
		||||
				self.stamina = self:memorize("stamina", self.stamina + self.dtime)
 | 
			
		||||
			end
 | 
			
		||||
			if self.stamina > 25
 | 
			
		||||
			and self.is_landed then
 | 
			
		||||
				self.is_landed = self:memorize("is_landed", false)
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			self.stamina = self:memorize("stamina", self.stamina + self.dtime)
 | 
			
		||||
			self.is_landed = self:memorize("is_landed", true)
 | 
			
		||||
		end
 | 
			
		||||
		if self._anim == "fly" then
 | 
			
		||||
			local vel_y = self.object:get_velocity().y
 | 
			
		||||
			local rot = self.object:get_rotation()
 | 
			
		||||
			self.object:set_rotation({
 | 
			
		||||
				x = clamp(vel_y * 0.25, -0.75, 0.75),
 | 
			
		||||
				y = rot.y,
 | 
			
		||||
				z = rot.z
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
		if self:timer(random(3,4)) then
 | 
			
		||||
			self:play_sound("random")
 | 
			
		||||
			if guano_accumulation
 | 
			
		||||
			and random(16) < 2
 | 
			
		||||
			and self:get_utility() == "animalia:return_to_home" then
 | 
			
		||||
				local pos = self.object:get_pos()
 | 
			
		||||
				pos = {
 | 
			
		||||
					x = floor(pos.x + 0.5),
 | 
			
		||||
					y = floor(pos.y + 0.5),
 | 
			
		||||
					z = floor(pos.z + 0.5)
 | 
			
		||||
				}
 | 
			
		||||
				if not is_node_walkable(minetest.get_node(vec_raise(pos, 1)).name) then
 | 
			
		||||
					return
 | 
			
		||||
				end
 | 
			
		||||
				local fail_safe = 1
 | 
			
		||||
				while not is_node_walkable(minetest.get_node(floor_pos).name)
 | 
			
		||||
				and fail_safe < 16 do
 | 
			
		||||
					pos.y = pos.y - 1
 | 
			
		||||
				end
 | 
			
		||||
				if is_node_walkable(minetest.get_node(pos).name) then
 | 
			
		||||
					if minetest.get_node(vec_raise(pos, 1)).name ~= "animalia:guano" then
 | 
			
		||||
						minetest.set_node(vec_raise(pos, 1), {name = "animalia:guano"})
 | 
			
		||||
					else
 | 
			
		||||
						local nodes = minetest.find_nodes_in_area_under_air(
 | 
			
		||||
							vector.subtract(pos, 3),
 | 
			
		||||
							vec_add(pos, 3),
 | 
			
		||||
							animalia.walkable_nodes
 | 
			
		||||
						)
 | 
			
		||||
						if #nodes > 0 then
 | 
			
		||||
							pos = nodes[random(#nodes)]
 | 
			
		||||
							if minetest.get_node(vec_raise(pos, 1)).name ~= "animalia:guano" then
 | 
			
		||||
								minetest.set_node(vec_raise(pos, 1), {name = "animalia:guano"})
 | 
			
		||||
							end
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed(self, clicker, false, false) then
 | 
			
		||||
			self.trust[clicker:get_player_name()] = 1
 | 
			
		||||
			self:memorize("trust", self.trust)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "bat", form = "pg_bat;Bats"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self.trust[puncher:get_player_name()] = 0
 | 
			
		||||
		self:memorize("trust", self.trust)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_spawn_egg("animalia:bat", "392517", "321b0b")
 | 
			
		||||
							
								
								
									
										182
									
								
								mobs/bird.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										182
									
								
								mobs/bird.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,182 @@
 | 
			
		||||
---------------
 | 
			
		||||
-- Song Bird --
 | 
			
		||||
---------------
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local function clamp(val, min, max)
 | 
			
		||||
	if val < min then
 | 
			
		||||
		val = min
 | 
			
		||||
	elseif max < val then
 | 
			
		||||
		val = max
 | 
			
		||||
	end
 | 
			
		||||
	return val
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
creatura.register_mob("animalia:bird", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 5,
 | 
			
		||||
    armor_groups = {fleshy = 200},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 4,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 100,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 100,
 | 
			
		||||
	turn_rate = 6,
 | 
			
		||||
	boid_seperation = 1,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_bird.b3d",
 | 
			
		||||
    hitbox = {
 | 
			
		||||
		width = 0.15,
 | 
			
		||||
		height = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_bird_cardinal.png",
 | 
			
		||||
		"animalia_bird_eastern_blue.png",
 | 
			
		||||
		"animalia_bird_goldfinch.png"
 | 
			
		||||
	},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 50, y = 70}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
        fly = {range = {x = 120, y = 140}, speed = 80, frame_blend = 0.3, loop = true}
 | 
			
		||||
		},
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
		cardinal = {
 | 
			
		||||
            name = "animalia_cardinal",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
            distance = 63,
 | 
			
		||||
			variations = 3
 | 
			
		||||
        },
 | 
			
		||||
		eastern_blue = {
 | 
			
		||||
            name = "animalia_eastern_blue",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
            distance = 63,
 | 
			
		||||
			variations = 3
 | 
			
		||||
        },
 | 
			
		||||
        goldfinch = {
 | 
			
		||||
            name = "animalia_goldfinch",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
            distance = 63,
 | 
			
		||||
			variations = 3
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:boid_wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:aerial_flock",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.is_landed then
 | 
			
		||||
					return 0.11, {self, 1}
 | 
			
		||||
				else
 | 
			
		||||
					local pos = self.object:get_pos()
 | 
			
		||||
					if self.in_liquid then
 | 
			
		||||
						self.stamina = self:memorize("stamina", 30)
 | 
			
		||||
						self.is_landed = false
 | 
			
		||||
						return 0.15, {self, 1}
 | 
			
		||||
					end
 | 
			
		||||
					local player = creatura.get_nearby_player(self)
 | 
			
		||||
					if player then
 | 
			
		||||
						local dist = vector.distance(pos, player:get_pos())
 | 
			
		||||
						self.is_landed = false
 | 
			
		||||
						return (16 - dist) * 0.1, {self, 1}
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.is_landed
 | 
			
		||||
				and not self.touching_ground
 | 
			
		||||
				and not self.in_liquid then
 | 
			
		||||
					return 0.12, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
		self.trust = self:recall("trust") or {}
 | 
			
		||||
		self.is_landed = self:recall("is_landed") or true
 | 
			
		||||
		self.stamina = self:recall("stamina") or 0.1
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
		if self:timer(random(10,15)) then
 | 
			
		||||
			if self.texture_no == 1 then
 | 
			
		||||
				self:play_sound("cardinal")
 | 
			
		||||
			elseif self.texture_no == 2 then
 | 
			
		||||
				self:play_sound("eastern_blue")
 | 
			
		||||
			else
 | 
			
		||||
				self:play_sound("goldfinch")
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		if self._anim == "fly" then
 | 
			
		||||
			local vel_y = self.object:get_velocity().y
 | 
			
		||||
			local rot = self.object:get_rotation()
 | 
			
		||||
			self.object:set_rotation({
 | 
			
		||||
				x = clamp(vel_y * 0.25, -0.75, 0.75),
 | 
			
		||||
				y = rot.y,
 | 
			
		||||
				z = rot.z
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
		if self.stamina > 0 then
 | 
			
		||||
			if not self.is_landed then
 | 
			
		||||
				self.stamina = self:memorize("stamina", self.stamina - self.dtime)
 | 
			
		||||
			else
 | 
			
		||||
				self.stamina = self:memorize("stamina", self.stamina + self.dtime)
 | 
			
		||||
			end
 | 
			
		||||
			if self.stamina > 25
 | 
			
		||||
			and self.is_landed then
 | 
			
		||||
				self.is_landed = self:memorize("is_landed", false)
 | 
			
		||||
			end
 | 
			
		||||
		else
 | 
			
		||||
			self.stamina = self:memorize("stamina", self.stamina + self.dtime)
 | 
			
		||||
			self.is_landed = self:memorize("is_landed", true)
 | 
			
		||||
		end
 | 
			
		||||
		if not self.is_landed
 | 
			
		||||
		or not self.touching_ground then
 | 
			
		||||
			self.speed = 4
 | 
			
		||||
		else
 | 
			
		||||
			self.speed = 1
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed(self, clicker, false, false) then
 | 
			
		||||
			self.trust[clicker:get_player_name()] = 1
 | 
			
		||||
			self:memorize("trust", self.trust)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "bird", form = "pg_bird;Birds"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self.trust[puncher:get_player_name()] = 0
 | 
			
		||||
		self:memorize("trust", self.trust)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_spawn_egg("animalia:bird", "ae2f2f", "f3ac1c")
 | 
			
		||||
							
								
								
									
										451
									
								
								mobs/cat.lua
									
									
									
									
									
								
							
							
						
						
									
										451
									
								
								mobs/cat.lua
									
									
									
									
									
								
							@ -2,10 +2,6 @@
 | 
			
		||||
-- Cat --
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
 | 
			
		||||
local follow = {
 | 
			
		||||
	"animalia:poultry_raw"
 | 
			
		||||
}
 | 
			
		||||
@ -17,146 +13,23 @@ if minetest.registered_items["ethereal:fish_raw"] then
 | 
			
		||||
	}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function cat_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then	
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self._anim == "run" then
 | 
			
		||||
		local pos = self.object:get_pos()
 | 
			
		||||
		minetest.add_particlespawner({
 | 
			
		||||
			amount = 1,
 | 
			
		||||
			time = 0.25,
 | 
			
		||||
			minpos = pos,
 | 
			
		||||
			maxpos = pos,
 | 
			
		||||
			minvel = vector.new(-1, 1, -1),
 | 
			
		||||
			maxvel = vector.new(1, 2, 1),
 | 
			
		||||
			minacc = vector.new(0, -9.81, 0),
 | 
			
		||||
			maxacc = vector.new(0, -9.81, 0),
 | 
			
		||||
			minsize = 0.25,
 | 
			
		||||
			maxsize = 0.5,
 | 
			
		||||
			collisiondetection = true,
 | 
			
		||||
			texture = "default_dirt.png",
 | 
			
		||||
		})
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.25, 0.25)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 1) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
		local trust = 0
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 64)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if player then
 | 
			
		||||
			if not self.trust[player:get_player_name()] then
 | 
			
		||||
				self.trust[player:get_player_name()] = 0
 | 
			
		||||
				mobkit.remember(self, "trust", self.trust)
 | 
			
		||||
			else
 | 
			
		||||
				trust = self.trust[player:get_player_name()]
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if self.trust_cooldown > 0 then
 | 
			
		||||
			self.trust_cooldown = mobkit.remember(self, "trust_cooldown", self.trust_cooldown - 1)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if self.interact_sound_cooldown > 0 then
 | 
			
		||||
			self.interact_sound_cooldown = self.interact_sound_cooldown - 1
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and self.trust[self.owner] > 7 then
 | 
			
		||||
			if prty < 22
 | 
			
		||||
			and self.order == "sit" then
 | 
			
		||||
				if not mobkit.is_queue_empty_high(self) then
 | 
			
		||||
					mobkit.clear_queue_high(self)
 | 
			
		||||
				end
 | 
			
		||||
				mobkit.animate(self, "sit")
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
	
 | 
			
		||||
			if prty < 21
 | 
			
		||||
			and self.owner_target then
 | 
			
		||||
				if not mob_core.shared_owner(self, self.owner_target) then
 | 
			
		||||
					animalia.hq_attack(self, 21, self.owner_target)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
	
 | 
			
		||||
			if prty < 20
 | 
			
		||||
			and self.order == "follow"
 | 
			
		||||
			and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
				local owner = minetest.get_player_by_name(self.owner)
 | 
			
		||||
				animalia.hq_follow_player(self, 20, owner, true)
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if prty < 4
 | 
			
		||||
			and self.breeding then
 | 
			
		||||
				animalia.hq_breed(self, 3)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 5
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 5)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
		and player then
 | 
			
		||||
			if player:get_velocity()
 | 
			
		||||
			and vector.length(player:get_velocity()) < 2 then
 | 
			
		||||
				if mob_core.follow_holding(self, player)
 | 
			
		||||
				and trust >= 4 then
 | 
			
		||||
					animalia.hq_follow_player(self, 3, player)
 | 
			
		||||
				end
 | 
			
		||||
			elseif player:get_wielded_item():get_name() == "animalia:cat_toy" then
 | 
			
		||||
				animalia.hq_follow_player(self, 3, player, true)
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		
 | 
			
		||||
		if player
 | 
			
		||||
		and prty == 3
 | 
			
		||||
		and not mob_core.follow_holding(self, player)
 | 
			
		||||
		and player:get_wielded_item():get_name() ~= "animalia:cat_toy" then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 2
 | 
			
		||||
		and player
 | 
			
		||||
		and trust > 4 then
 | 
			
		||||
			local r = math.random(48)
 | 
			
		||||
			if r < 2 then
 | 
			
		||||
				animalia.hq_walk_in_front_of_player(self, 2, player)
 | 
			
		||||
			elseif r < 3 then
 | 
			
		||||
				animalia.hq_find_and_break_glass(self, 2)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_ranged(self, 0)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("cat", {
 | 
			
		||||
creatura.register_mob("animalia:cat", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 10,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.2, 0, -0.2, 0.2, 0.4, 0.2},
 | 
			
		||||
    max_health = 10,
 | 
			
		||||
    armor_groups = {fleshy = 200},
 | 
			
		||||
    damage = 1,
 | 
			
		||||
    speed = 5,
 | 
			
		||||
	tracking_range = 24,
 | 
			
		||||
    despawn_after = 2000,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_cat.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.2,
 | 
			
		||||
		height = 0.4
 | 
			
		||||
	},
 | 
			
		||||
	visual_size = {x = 6, y = 6},
 | 
			
		||||
	scale_stage1 = 0.5,
 | 
			
		||||
    scale_stage2 = 0.65,
 | 
			
		||||
    scale_stage3 = 0.80,
 | 
			
		||||
	mesh = "animalia_cat.b3d",
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_cat_1.png",
 | 
			
		||||
		"animalia_cat_2.png",
 | 
			
		||||
@ -170,12 +43,9 @@ animalia.register_mob("cat", {
 | 
			
		||||
		sit = {range = {x = 140, y = 180}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		smack = {range = {x = 190, y = 210}, speed = 40, frame_blend = 0.1, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 8,
 | 
			
		||||
    max_fall = 4,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_cat_idle",
 | 
			
		||||
            gain = 0.25,
 | 
			
		||||
@ -197,97 +67,244 @@ animalia.register_mob("cat", {
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
	},
 | 
			
		||||
	reach = 2,
 | 
			
		||||
    damage = 3,
 | 
			
		||||
    knockback = 2,
 | 
			
		||||
    punch_cooldown = 1,
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = true,
 | 
			
		||||
	follow = follow,
 | 
			
		||||
    -- Functions
 | 
			
		||||
    follow = follow,
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.17, z = 0},
 | 
			
		||||
		offset = {x = 0, y = 0.22, z = 0},
 | 
			
		||||
		pitch_correction = -20,
 | 
			
		||||
		pivot_h = 0.35,
 | 
			
		||||
		pivot_v = 0.2
 | 
			
		||||
		pivot_h = 0.65,
 | 
			
		||||
		pivot_v = 0.65
 | 
			
		||||
	},
 | 
			
		||||
    logic = cat_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = function(self, staticdata, dtime_s)
 | 
			
		||||
		animalia.on_activate(self, staticdata, dtime_s)
 | 
			
		||||
		self.trust = mobkit.recall(self, "trust") or {}
 | 
			
		||||
		self.trust_cooldown = mobkit.recall(self, "trust_cooldown") or 0
 | 
			
		||||
    -- Function
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		self.interact_sound_cooldown = 0
 | 
			
		||||
	end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		local item = clicker:get_wielded_item():get_name()
 | 
			
		||||
		if item == "animalia:net" then return end
 | 
			
		||||
		if not self.trust[clicker:get_player_name()] then
 | 
			
		||||
			self.trust[clicker:get_player_name()] = 0
 | 
			
		||||
			mobkit.remember(self, "trust", self.trust)
 | 
			
		||||
		self.trust_cooldown = self:recall("trust_cooldown") or 0
 | 
			
		||||
		self.order = self:recall("order") or "wander"
 | 
			
		||||
		self.owner = self:recall("owner") or nil
 | 
			
		||||
		self.trust = self:recall("trust") or {}
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
			if not animalia.pets[self.owner][self.object] then
 | 
			
		||||
				table.insert(animalia.pets[self.owner], self.object)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		local trust = self.trust[clicker:get_player_name()]
 | 
			
		||||
		local pos = self.object:get_pos()
 | 
			
		||||
		local prt_pos = vector.new(pos.x, pos.y + 0.5, pos.z)
 | 
			
		||||
		local minppos = vector.add(prt_pos, 1)
 | 
			
		||||
		local maxppos = vector.subtract(prt_pos, 1)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, math.random(3, 5), trust >= 10, trust >= 10) then
 | 
			
		||||
    end,
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:find_and_break_glass_vessels",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return math.random(10) * 0.01, {self}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:walk_ahead_of_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player then
 | 
			
		||||
					local trust = 0
 | 
			
		||||
					if not self.trust[player:get_player_name()] then
 | 
			
		||||
						self.trust[player:get_player_name()] = 0
 | 
			
		||||
						self:memorize("trust", self.trust)
 | 
			
		||||
					else
 | 
			
		||||
						trust = self.trust[player:get_player_name()]
 | 
			
		||||
					end
 | 
			
		||||
					self._nearby_player = player
 | 
			
		||||
					if trust > 3 then
 | 
			
		||||
						return math.random(10) * 0.01, {self, player}
 | 
			
		||||
					else
 | 
			
		||||
						return 0
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:flee_from_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player then
 | 
			
		||||
					local trust = self.trust[player:get_player_name()] or 0
 | 
			
		||||
					if trust < 1 then
 | 
			
		||||
						if self.owner
 | 
			
		||||
						and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
							local pos = self.object:get_pos()
 | 
			
		||||
							local owner = minetest.get_player_by_name(self.owner)
 | 
			
		||||
							local owner_pos = owner:get_pos()
 | 
			
		||||
							if owner ~= player
 | 
			
		||||
							and vector.distance(pos, owner_pos) < vector.distance(pos, player:get_pos()) then
 | 
			
		||||
								return 0 
 | 
			
		||||
							end
 | 
			
		||||
						end
 | 
			
		||||
						return 0.5, {self, player}
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[6] = {
 | 
			
		||||
			utility = "animalia:sit",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.order == "sit"
 | 
			
		||||
				and self.trust[self.owner] > 7 then
 | 
			
		||||
					return 0.8, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[7] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.order == "follow"
 | 
			
		||||
				and minetest.get_player_by_name(self.owner)
 | 
			
		||||
				and self.trust[self.owner] > 7 then
 | 
			
		||||
					return 1, {self, minetest.get_player_by_name(self.owner)}
 | 
			
		||||
				end
 | 
			
		||||
				local trust = 0
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player then
 | 
			
		||||
					if not self.trust[player:get_player_name()] then
 | 
			
		||||
						self.trust[player:get_player_name()] = 0
 | 
			
		||||
						self:memorize("trust", self.trust)
 | 
			
		||||
					else
 | 
			
		||||
						trust = self.trust[player:get_player_name()]
 | 
			
		||||
					end
 | 
			
		||||
				else
 | 
			
		||||
					return 0
 | 
			
		||||
				end
 | 
			
		||||
				if player:get_velocity()
 | 
			
		||||
				and vector.length(player:get_velocity()) < 2
 | 
			
		||||
				and self:follow_wielded_item(player)
 | 
			
		||||
				and trust >= 4 then
 | 
			
		||||
					return 0.6, {self, player}
 | 
			
		||||
				elseif player:get_wielded_item():get_name() == "animalia:cat_toy" then
 | 
			
		||||
					return 0.6, {self, player, true}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[8] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.7, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
		if self:timer(1) then
 | 
			
		||||
			if self.trust_cooldown > 0 then
 | 
			
		||||
				self.trust_cooldown = self:memorize("trust_cooldown", self.trust_cooldown - 1)
 | 
			
		||||
			end
 | 
			
		||||
			if self.interact_sound_cooldown > 0 then
 | 
			
		||||
				self.interact_sound_cooldown = self.interact_sound_cooldown - 1
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		local item_name = clicker:get_wielded_item():get_name()
 | 
			
		||||
		if item_name == "animalia:net" then return end
 | 
			
		||||
		local trust = self.trust[clicker:get_player_name()] or 0
 | 
			
		||||
		local pos = self:get_center_pos()
 | 
			
		||||
		local minppos = vector.add(pos, 1)
 | 
			
		||||
		local maxppos = vector.subtract(pos, 1)
 | 
			
		||||
		if animalia.feed(self, clicker, true, true) then
 | 
			
		||||
			if self.trust_cooldown <= 0
 | 
			
		||||
			and trust < 10 then
 | 
			
		||||
				self.trust[clicker:get_player_name()] = trust + 1
 | 
			
		||||
				self.trust_cooldown = mobkit.remember(self, "trust_cooldown", 60)
 | 
			
		||||
				mobkit.remember(self, "trust", self.trust)
 | 
			
		||||
				animalia.particle_spawner(prt_pos, "mob_core_green_particle.png", "float", minppos, maxppos)
 | 
			
		||||
				self.trust_cooldown = self:memorize("trust_cooldown", 60)
 | 
			
		||||
				self:memorize("trust", self.trust)
 | 
			
		||||
				animalia.particle_spawner(pos, "creatura_particle_green.png", "float", minppos, maxppos)
 | 
			
		||||
			end
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		if mobkit.get_queue_priority(self) == 3
 | 
			
		||||
		and clicker:get_wielded_item():get_name() == "animalia:cat_toy" then
 | 
			
		||||
		-- Initiate trust
 | 
			
		||||
		if not self.trust[clicker:get_player_name()] then
 | 
			
		||||
			self.trust[clicker:get_player_name()] = 0
 | 
			
		||||
			self:memorize("trust", self.trust)
 | 
			
		||||
		end
 | 
			
		||||
		-- Increase trust by playing
 | 
			
		||||
		if item_name == "animalia:cat_toy"
 | 
			
		||||
		and self:get_utility() == "animalia:follow_player" then
 | 
			
		||||
			if trust < 10 then
 | 
			
		||||
				self.trust[clicker:get_player_name()] = trust + 1
 | 
			
		||||
				mobkit.remember(self, "trust", self.trust)
 | 
			
		||||
				animalia.particle_spawner(prt_pos, "mob_core_green_particle.png", "float", minppos, maxppos)
 | 
			
		||||
				self:memorize("trust", self.trust)
 | 
			
		||||
				animalia.particle_spawner(pos, "creatura_particle_green.png", "float", minppos, maxppos)
 | 
			
		||||
				if self.interact_sound_cooldown <= 0 then
 | 
			
		||||
					self.sounds["purr"].gain = 1
 | 
			
		||||
					self.interact_sound_cooldown = 3
 | 
			
		||||
					mobkit.make_sound(self, "purr")
 | 
			
		||||
					self:play_sound("purr")
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		-- Purr to indicate trust level (louder = more trust)
 | 
			
		||||
		if clicker:get_player_control().sneak then
 | 
			
		||||
			if self.interact_sound_cooldown <= 0 then
 | 
			
		||||
				self.sounds["purr"].gain = 0.15 * trust
 | 
			
		||||
				self.interact_sound_cooldown = 3
 | 
			
		||||
				self:play_sound("purr")
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "cat", form = "pg_cat;Cats"})
 | 
			
		||||
		if not self.owner
 | 
			
		||||
		or clicker:get_player_name() ~= self.owner then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if trust <= 7 then
 | 
			
		||||
			if self.interact_sound_cooldown <= 0 then
 | 
			
		||||
				self.interact_sound_cooldown = 3
 | 
			
		||||
				self:play_sound("random")
 | 
			
		||||
			end
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if clicker:get_player_control().sneak then
 | 
			
		||||
			if self.interact_sound_cooldown <= 0 then
 | 
			
		||||
				self.sounds["purr"].gain = 0.15 * self.trust[self.owner]
 | 
			
		||||
				self.interact_sound_cooldown = 3
 | 
			
		||||
				mobkit.make_sound(self, "purr")
 | 
			
		||||
				self:play_sound("purr")
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		if trust <= 7 then
 | 
			
		||||
			if self.interact_sound_cooldown <= 0 then
 | 
			
		||||
				self.interact_sound_cooldown = 3
 | 
			
		||||
				mobkit.make_sound(self, "random")
 | 
			
		||||
			local order = self.order
 | 
			
		||||
			if order == "wander" then
 | 
			
		||||
				self.order = "follow"
 | 
			
		||||
			elseif order == "follow" then
 | 
			
		||||
				self.order = "sit"
 | 
			
		||||
			else
 | 
			
		||||
				self.order = "wander"
 | 
			
		||||
			end
 | 
			
		||||
			return
 | 
			
		||||
			self:memorize("order", self.order)
 | 
			
		||||
		end
 | 
			
		||||
		if self.order == "wander" then
 | 
			
		||||
			self.order = "follow"
 | 
			
		||||
		elseif self.order == "follow" then
 | 
			
		||||
			self.order = "sit"
 | 
			
		||||
		else
 | 
			
		||||
			self.order = "wander"
 | 
			
		||||
		end
 | 
			
		||||
		mobkit.remember(self, "order", self.order)
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:flee_from_player", self, puncher)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
		if not self.trust[puncher:get_player_name()] then
 | 
			
		||||
			self.trust[puncher:get_player_name()] = 0
 | 
			
		||||
		else
 | 
			
		||||
@ -295,12 +312,18 @@ animalia.register_mob("cat", {
 | 
			
		||||
			self.trust[puncher:get_player_name()] = trust - 1
 | 
			
		||||
		end
 | 
			
		||||
		local pos = self.object:get_pos()
 | 
			
		||||
		local prt_pos = vector.new(pos.x, pos.y + 0.5, pos.z)
 | 
			
		||||
		local minppos = vector.add(prt_pos, 1)
 | 
			
		||||
		local maxppos = vector.subtract(prt_pos, 1)
 | 
			
		||||
		animalia.particle_spawner(prt_pos, "mob_core_red_particle.png", "float", minppos, maxppos)
 | 
			
		||||
		mobkit.remember(self, "trust", self.trust)
 | 
			
		||||
		pos = vector.new(pos.x, pos.y + 0.5, pos.z)
 | 
			
		||||
		local minppos = vector.add(pos, 1)
 | 
			
		||||
		local maxppos = vector.subtract(pos, 1)
 | 
			
		||||
		animalia.particle_spawner(pos, "creatura_particle_red.png", "float", minppos, maxppos)
 | 
			
		||||
		self:memorize("trust", self.trust)
 | 
			
		||||
	end,
 | 
			
		||||
	deactivate_func = function(self)
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and animalia.pets[self.owner][self.object] then
 | 
			
		||||
			animalia.pets[self.owner][self.object] = nil
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:cat", "db9764" ,"cf8d5a")
 | 
			
		||||
creatura.register_spawn_egg("animalia:cat", "db9764" ,"cf8d5a")
 | 
			
		||||
							
								
								
									
										356
									
								
								mobs/chicken.lua
									
									
									
									
									
								
							
							
						
						
									
										356
									
								
								mobs/chicken.lua
									
									
									
									
									
								
							@ -2,91 +2,36 @@
 | 
			
		||||
-- Chicken --
 | 
			
		||||
-------------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local function chicken_logic(self)
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.fall_start
 | 
			
		||||
	and self.fall_start - mobkit.get_stand_pos(self).y > 2 then
 | 
			
		||||
		mobkit.animate(self, "flap")
 | 
			
		||||
		self.object:set_acceleration({x = 0, y = -3.1, z = 0})
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.45, 0.25)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 4) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
		mob_core.random_drop(self, 10, 1800, "animalia:chicken_egg")
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_fowl_breed(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
				if self.attention_span < 5 then
 | 
			
		||||
					if mob_core.follow_holding(self, player) then
 | 
			
		||||
						animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
						self.attention_span = self.attention_span + 1
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if name:match(":seed_")
 | 
			
		||||
		or name:match("_seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 8)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("chicken", {
 | 
			
		||||
	-- Stats
 | 
			
		||||
	health = 10,
 | 
			
		||||
	fleshy = 100,
 | 
			
		||||
	view_range = 8,
 | 
			
		||||
	lung_capacity = 10,
 | 
			
		||||
	-- Visual
 | 
			
		||||
	collisionbox = {-0.2, -0.15, -0.2, 0.2, 0.3, 0.2},
 | 
			
		||||
	visual_size = {x = 6, y = 6},
 | 
			
		||||
	mesh = "animalia_chicken.b3d",
 | 
			
		||||
creatura.register_mob("animalia:chicken", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 5,
 | 
			
		||||
    armor_groups = {fleshy = 150},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 4,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 8,
 | 
			
		||||
	turn_rate = 7,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_chicken.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.15,
 | 
			
		||||
		height = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	female_textures = {
 | 
			
		||||
		"animalia_chicken_1.png",
 | 
			
		||||
		"animalia_chicken_2.png",
 | 
			
		||||
@ -102,14 +47,11 @@ animalia.register_mob("chicken", {
 | 
			
		||||
		stand = {range = {x = 0, y = 0}, speed = 1, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 10, y = 30}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 10, y = 30}, speed = 45, frame_blend = 0.3, loop = true},
 | 
			
		||||
        fall = {range = {x = 40, y = 60}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
        fall = {range = {x = 40, y = 60}, speed = 70, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
	-- Physics
 | 
			
		||||
	speed = 5,
 | 
			
		||||
	max_fall = 6,
 | 
			
		||||
	-- Attributes
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_chicken_idle",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
@ -126,172 +68,96 @@ animalia.register_mob("chicken", {
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
	fall_damage = false,
 | 
			
		||||
	-- Behavior
 | 
			
		||||
	defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:seed_cotton",
 | 
			
		||||
		"farming:seed_wheat"
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:feather", chance = 1, min = 1, max = 2},
 | 
			
		||||
		{name = "animalia:poultry_raw", chance = 1, min = 1, max = 4}
 | 
			
		||||
	},
 | 
			
		||||
	-- Functions
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:poultry_raw", min = 1, max = 3, chance = 1},
 | 
			
		||||
		{name = "animalia:feather", min = 1, max = 3, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.15, z = 0},
 | 
			
		||||
		pitch_correction = 55,
 | 
			
		||||
		pivot_h = 0.25,
 | 
			
		||||
		pivot_v = 0.55
 | 
			
		||||
	},
 | 
			
		||||
	logic = chicken_logic,
 | 
			
		||||
	get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
    on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	end,
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:chicken", "c6c6c6", "d22222")
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:poultry_raw", {
 | 
			
		||||
	description = "Raw Poultry",
 | 
			
		||||
	inventory_image = "animalia_poultry_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:poultry_cooked", {
 | 
			
		||||
	description = "Cooked Poultry",
 | 
			
		||||
	inventory_image = "animalia_poultry_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(6),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:poultry_raw",
 | 
			
		||||
	output = "animalia:poultry_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_entity("animalia:chicken_egg_sprite", {
 | 
			
		||||
    hp_max = 1,
 | 
			
		||||
    physical = true,
 | 
			
		||||
    collisionbox = {0, 0, 0, 0, 0, 0},
 | 
			
		||||
    visual = "sprite",
 | 
			
		||||
    visual_size = {x = 0.5, y = 0.5},
 | 
			
		||||
    textures = {"animalia_egg.png"},
 | 
			
		||||
    initial_sprite_basepos = {x = 0, y = 0},
 | 
			
		||||
    is_visible = true,
 | 
			
		||||
	on_step = function(self, dtime)
 | 
			
		||||
		local pos = self.object:get_pos()
 | 
			
		||||
		local objects = minetest.get_objects_inside_radius(pos, 1.5)
 | 
			
		||||
		local cube = minetest.find_nodes_in_area(
 | 
			
		||||
			vector.new(pos.x - 0.5, pos.y - 0.5, pos.z - 0.5),
 | 
			
		||||
			vector.new(pos.x + 0.5, pos.y + 0.5, pos.z + 0.5),
 | 
			
		||||
			animalia.walkable_nodes)
 | 
			
		||||
		if #objects >= 2 then
 | 
			
		||||
			if objects[2]:get_armor_groups().fleshy then
 | 
			
		||||
				objects[2]:punch(self.object, 2.0, {full_punch_interval = 0.1, damage_groups = {fleshy = 1}}, nil)
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		if #cube >= 1 then
 | 
			
		||||
			minetest.add_particlespawner({
 | 
			
		||||
				amount = 6,
 | 
			
		||||
				time = 0.25,
 | 
			
		||||
				minpos = {x = pos.x - 7/16, y = pos.y - 5/16, z = pos.z - 7/16},
 | 
			
		||||
				maxpos = {x = pos.x + 7/16, y = pos.y - 5/16, z = pos.z + 7/16},
 | 
			
		||||
				minvel = vector.new(-1, 2, -1),
 | 
			
		||||
				maxvel = vector.new(1, 5, 1),
 | 
			
		||||
				minacc = vector.new(0, -9.81, 0),
 | 
			
		||||
				maxacc = vector.new(0, -9.81, 0),
 | 
			
		||||
				collisiondetection = true,
 | 
			
		||||
				texture = "animalia_egg_fragment.png",
 | 
			
		||||
			})
 | 
			
		||||
			if random(1, 3) < 2 then
 | 
			
		||||
				mob_core.spawn_child(pos, "animalia:chicken")
 | 
			
		||||
				self.object:remove()
 | 
			
		||||
			else
 | 
			
		||||
				self.object:remove()
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:resist_fall",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.touching_ground then
 | 
			
		||||
					return 0.11, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:bird_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "chicken", form = "pg_chicken;Chickens"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:flee_from_player", self, puncher)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local mobs_shoot_egg = function (item, player, pointed_thing)
 | 
			
		||||
	local pos = player:get_pos()
 | 
			
		||||
 | 
			
		||||
	minetest.sound_play("default_place_node_hard", {
 | 
			
		||||
		pos = pos,
 | 
			
		||||
		gain = 1.0,
 | 
			
		||||
		max_hear_distance = 5,
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	local vel = 19
 | 
			
		||||
	local gravity = 9
 | 
			
		||||
 | 
			
		||||
	local obj = minetest.add_entity({
 | 
			
		||||
		x = pos.x,
 | 
			
		||||
		y = pos.y +1.5,
 | 
			
		||||
		z = pos.z
 | 
			
		||||
	}, "animalia:chicken_egg_sprite")
 | 
			
		||||
 | 
			
		||||
	local ent = obj:get_luaentity()
 | 
			
		||||
	local dir = player:get_look_dir()
 | 
			
		||||
 | 
			
		||||
	ent.velocity = vel -- needed for api internal timing
 | 
			
		||||
	ent.switch = 1 -- needed so that egg doesn't despawn straight away
 | 
			
		||||
 | 
			
		||||
	obj:set_velocity({
 | 
			
		||||
		x = dir.x * vel,
 | 
			
		||||
		y = dir.y * vel,
 | 
			
		||||
		z = dir.z * vel
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	obj:set_acceleration({
 | 
			
		||||
		x = dir.x * -3,
 | 
			
		||||
		y = -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
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:chicken_egg", {
 | 
			
		||||
	description = "Chicken Egg",
 | 
			
		||||
	inventory_image = "animalia_egg.png",
 | 
			
		||||
	on_use = mobs_shoot_egg,
 | 
			
		||||
	groups = {food_egg = 1, flammable = 2},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:chicken_egg_fried", {
 | 
			
		||||
	description = "Fried Chicken Egg",
 | 
			
		||||
	inventory_image = "animalia_egg_fried.png",
 | 
			
		||||
	on_use = minetest.item_eat(4),
 | 
			
		||||
	groups = {food_egg = 1, flammable = 2},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:chicken_egg",
 | 
			
		||||
	output = "animalia:chicken_egg_fried",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:feather", {
 | 
			
		||||
	description = "Feather",
 | 
			
		||||
	inventory_image = "animalia_feather.png",
 | 
			
		||||
	groups = {flammable = 2, feather = 1},
 | 
			
		||||
})
 | 
			
		||||
creatura.register_spawn_egg("animalia:chicken", "c6c6c6", "d22222")
 | 
			
		||||
							
								
								
									
										282
									
								
								mobs/cow.lua
									
									
									
									
									
								
							
							
						
						
									
										282
									
								
								mobs/cow.lua
									
									
									
									
									
								
							@ -2,97 +2,36 @@
 | 
			
		||||
-- Cow --
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
local blend = animalia.frame_blend
 | 
			
		||||
 | 
			
		||||
local function cow_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 3) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if random(1, 64) < 2 then
 | 
			
		||||
			self.gotten = mobkit.remember(self, "gotten", false)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 5
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 5)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_breed(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
		and self.gotten
 | 
			
		||||
		and random(1, 16) < 2 then
 | 
			
		||||
			animalia.hq_eat(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
				if self.attention_span < 5 then
 | 
			
		||||
					if mob_core.follow_holding(self, player) then
 | 
			
		||||
						animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
						self.attention_span = self.attention_span + 1
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if (name:match(":wheat")
 | 
			
		||||
		or minetest.get_item_group(name, "food_wheat") > 0)
 | 
			
		||||
		and not name:find("seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 10)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("cow", {
 | 
			
		||||
creatura.register_mob("animalia:cow", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 20,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.45, 0, -0.45, 0.45, 0.9, 0.45},
 | 
			
		||||
	visual_size = {x = 10, y = 10},
 | 
			
		||||
	mesh = "animalia_cow.b3d",
 | 
			
		||||
    max_health = 20,
 | 
			
		||||
    armor_groups = {fleshy = 150},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 3,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	turn_rate = 6,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_cow.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.45,
 | 
			
		||||
		height = 0.9
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 10, y = 10},
 | 
			
		||||
	female_textures = {
 | 
			
		||||
		"animalia_cow_1.png^animalia_cow_udder.png",
 | 
			
		||||
		"animalia_cow_2.png^animalia_cow_udder.png",
 | 
			
		||||
@ -114,35 +53,33 @@ animalia.register_mob("cow", {
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 70, y = 110}, speed = 60, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 4,
 | 
			
		||||
    max_fall = 3,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_cow_idle",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            distance = 8
 | 
			
		||||
            name = "animalia_cow_random",
 | 
			
		||||
            gain = 0.4,
 | 
			
		||||
            distance = 8,
 | 
			
		||||
			variations = 3
 | 
			
		||||
        },
 | 
			
		||||
        hurt = {
 | 
			
		||||
            name = "animalia_cow_hurt",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            gain = 0.4,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        },
 | 
			
		||||
        death = {
 | 
			
		||||
            name = "animalia_cow_death",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            gain = 0.4,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:wheat",
 | 
			
		||||
	},
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:beef_raw", min = 1, max = 3, chance = 1},
 | 
			
		||||
		{name = "animalia:leather", min = 1, max = 3, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	consumable_nodes = {
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dirt_with_grass",
 | 
			
		||||
@ -153,36 +90,95 @@ animalia.register_mob("cow", {
 | 
			
		||||
			replacement = "default:dry_dirt"
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:leather", chance = 2, min = 1, max = 2},
 | 
			
		||||
		{name = "animalia:beef_raw", chance = 1, min = 1, max = 4}
 | 
			
		||||
	},
 | 
			
		||||
    -- Functions
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.5, z = 0},
 | 
			
		||||
		pitch_correction = -45,
 | 
			
		||||
		pivot_h = 0.75,
 | 
			
		||||
		pivot_v = 1
 | 
			
		||||
	},
 | 
			
		||||
    logic = cow_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:eat_from_turf",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if math.random(25) < 2 then
 | 
			
		||||
					return 0.1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.gotten = self:recall("gotten") or false
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		local name = clicker:get_player_name()
 | 
			
		||||
 | 
			
		||||
		if tool:get_name() == "bucket:bucket_empty" then
 | 
			
		||||
 | 
			
		||||
			if self.child == true then
 | 
			
		||||
			if self.growth_scale < 1 then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			if self.gotten == true then
 | 
			
		||||
			if self.gotten then
 | 
			
		||||
				minetest.chat_send_player(name, "This Cow has already been milked.")
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
@ -195,53 +191,21 @@ animalia.register_mob("cow", {
 | 
			
		||||
			if inv:room_for_item("main", {name = "animalia:bucket_milk"}) then
 | 
			
		||||
				clicker:get_inventory():add_item("main", "animalia:bucket_milk")
 | 
			
		||||
			else
 | 
			
		||||
				local pos = self.object:get_pos()
 | 
			
		||||
				local pos = self:get_pos("floor")
 | 
			
		||||
				pos.y = pos.y + 0.5
 | 
			
		||||
				minetest.add_item(pos, {name = "animalia:bucket_milk"})
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			self.gotten = mobkit.remember(self, "gotten", true)
 | 
			
		||||
			self.gotten = self:memorize("gotten", true)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "cow", form = "pg_cow;Cows"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:flee_from_player", self, puncher)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:leather", {
 | 
			
		||||
    description = "Leather",
 | 
			
		||||
    inventory_image = "animalia_leather.png"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:bucket_milk", {
 | 
			
		||||
	description = "Bucket of Milk",
 | 
			
		||||
	inventory_image = "animalia_milk_bucket.png",
 | 
			
		||||
	stack_max = 1,
 | 
			
		||||
	on_use = minetest.item_eat(8, "bucket:bucket_empty"),
 | 
			
		||||
	groups = {food_milk = 1, flammable = 3},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:beef_raw", {
 | 
			
		||||
	description = "Raw Beef",
 | 
			
		||||
	inventory_image = "animalia_beef_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:beef_cooked", {
 | 
			
		||||
	description = "Steak",
 | 
			
		||||
	inventory_image = "animalia_beef_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(8),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:beef_raw",
 | 
			
		||||
	output = "animalia:beef_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:cow", "cac3a1" ,"464438")
 | 
			
		||||
creatura.register_spawn_egg("animalia:cow", "cac3a1" ,"464438")
 | 
			
		||||
							
								
								
									
										195
									
								
								mobs/frog.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										195
									
								
								mobs/frog.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,195 @@
 | 
			
		||||
----------
 | 
			
		||||
-- Frog --
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local vec_dist = vector.distance
 | 
			
		||||
 | 
			
		||||
creatura.register_mob("animalia:frog", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 5,
 | 
			
		||||
    armor_groups = {fleshy = 200},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 4,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 2500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 100,
 | 
			
		||||
	turn_rate = 10,
 | 
			
		||||
	bouyancy_multiplier = 0,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_frog.b3d",
 | 
			
		||||
    hitbox = {
 | 
			
		||||
		width = 0.15,
 | 
			
		||||
		height = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_frog_1.png",
 | 
			
		||||
		"animalia_frog_2.png"
 | 
			
		||||
	},
 | 
			
		||||
	child_textures = {
 | 
			
		||||
		"animalia_tadpole.png"
 | 
			
		||||
	},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		float = {range = {x = 90, y = 90}, speed = 1, frame_blend = 0.3, loop = true},
 | 
			
		||||
		swim = {range = {x = 90, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 50, y = 80}, speed = 50, frame_blend = 0.3, loop = true}
 | 
			
		||||
	},
 | 
			
		||||
    -- Misc
 | 
			
		||||
	makes_footstep_sound = true,
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
		random = {
 | 
			
		||||
            name = "animalia_frog",
 | 
			
		||||
            gain = 0.5,
 | 
			
		||||
            distance = 32,
 | 
			
		||||
			variations = 3
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    follow = {
 | 
			
		||||
		"butterflies:butterfly_red",
 | 
			
		||||
		"butterflies:butterfly_white",
 | 
			
		||||
		"butterflies:butterfly_violet"
 | 
			
		||||
	},
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.43, z = 0},
 | 
			
		||||
		pitch_correction = -15,
 | 
			
		||||
		pivot_h = 0.3,
 | 
			
		||||
		pivot_v = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:wander_water_surface",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 0.11, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:eat_bug_nodes",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local pos = self.object:get_pos()
 | 
			
		||||
				if math.random(12) * 0.01 then
 | 
			
		||||
					local food = minetest.find_nodes_in_area(vector.subtract(pos, 1.5), vector.add(pos, 1.5), self.follow)
 | 
			
		||||
					if food[1] then
 | 
			
		||||
						return 0.2, {self}
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:flop",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.in_liquid
 | 
			
		||||
				and self.growth_scale <= 0.6 then
 | 
			
		||||
					return 1
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:breed_water_surface",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding
 | 
			
		||||
				and self.in_liquid then
 | 
			
		||||
					return 1
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[6] = {
 | 
			
		||||
			utility = "animalia:flee_from_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then return 0 end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player then
 | 
			
		||||
					local trust = self.trust[player:get_player_name()] or 0
 | 
			
		||||
					self._nearby_player = player -- stored to memory to avoid calling get_nearby_player again
 | 
			
		||||
					return (10 - (vec_dist(self.object:get_pos(), player:get_pos()) + trust)) * 0.1, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[7] = {
 | 
			
		||||
			utility = "animalia:flee_to_water",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then return 0 end
 | 
			
		||||
				local pos = self.object:get_pos()
 | 
			
		||||
				local water = minetest.find_nodes_in_area(vector.subtract(pos, 1.5), vector.add(pos, 1.5), {"default:water_source"})
 | 
			
		||||
				if not water[1] then return 0 end
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player then
 | 
			
		||||
					local trust = self.trust[player:get_player_name()] or 0
 | 
			
		||||
					return (10 - (vec_dist(self.object:get_pos(), player:get_pos()) + trust)) * 0.1, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
		self.trust = self:recall("trust") or {}
 | 
			
		||||
		for i = 1, 15 do
 | 
			
		||||
			local frame = 120 + i
 | 
			
		||||
			local anim = {range = {x = frame, y = frame}, speed = 1, frame_blend = 0.3, loop = false}
 | 
			
		||||
			self.animations["tongue_" .. i] = anim
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.2, 0.2)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
		if self:timer(random(5, 10)) then
 | 
			
		||||
			self:play_sound("random")
 | 
			
		||||
		end
 | 
			
		||||
		local props = self.object:get_properties()
 | 
			
		||||
		if self.growth_scale <= 0.6
 | 
			
		||||
		and props.mesh ~= "animalia_tadpole.b3d" then
 | 
			
		||||
			self.object:set_properties({
 | 
			
		||||
				mesh = "animalia_tadpole.b3d"
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			local name = clicker:get_player_name()
 | 
			
		||||
			if self.trust[name] then
 | 
			
		||||
				self.trust[name] = self.trust[name] + 1
 | 
			
		||||
			else
 | 
			
		||||
				self.trust[name] = 1
 | 
			
		||||
			end
 | 
			
		||||
			if self.trust[name] > 5 then self.trust[name] = 5 end
 | 
			
		||||
			self:memorize("trust", self.trust)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "frog", form = "pg_frog;Frogs"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self.trust[puncher:get_player_name()] = 0
 | 
			
		||||
		self:memorize("trust", self.trust)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_spawn_egg("animalia:frog", "67942e", "294811")
 | 
			
		||||
							
								
								
									
										383
									
								
								mobs/horse.lua
									
									
									
									
									
								
							
							
						
						
									
										383
									
								
								mobs/horse.lua
									
									
									
									
									
								
							@ -4,14 +4,26 @@
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if (name:match(":wheat")
 | 
			
		||||
		or minetest.get_item_group(name, "food_wheat") > 0)
 | 
			
		||||
		and not name:find("seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local function set_pattern(self)
 | 
			
		||||
	local types = {
 | 
			
		||||
		"spots",
 | 
			
		||||
		"patches"
 | 
			
		||||
	}
 | 
			
		||||
    if mobkit.recall(self, "pattern")
 | 
			
		||||
	and not mobkit.recall(self, "pattern"):find("better_fauna") then
 | 
			
		||||
        local pattern = mobkit.recall(self, "pattern")
 | 
			
		||||
    if self:recall("pattern")
 | 
			
		||||
	and not self:recall("pattern"):find("better_fauna") then
 | 
			
		||||
        local pattern = self:recall("pattern")
 | 
			
		||||
        local texture = self.object:get_properties().textures[1]
 | 
			
		||||
        self.object:set_properties({
 | 
			
		||||
            textures = {texture .. "^" .. pattern}
 | 
			
		||||
@ -38,128 +50,29 @@ local function set_pattern(self)
 | 
			
		||||
        self.object:set_properties({
 | 
			
		||||
            textures = {texture .. "^" .. overlay}
 | 
			
		||||
        })
 | 
			
		||||
        mobkit.remember(self, "pattern", overlay)
 | 
			
		||||
        self:memorize("pattern", overlay)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function horse_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 1) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
		local pos = self.object:get_pos()
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 24)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if self.breaking then
 | 
			
		||||
			if not minetest.get_player_by_name(self.breaker)
 | 
			
		||||
			or not self.driver then
 | 
			
		||||
				self.breaking = nil
 | 
			
		||||
				self.breaker = nil
 | 
			
		||||
			else
 | 
			
		||||
				local yaw = self.object:get_yaw()
 | 
			
		||||
				local yaw2 = minetest.get_player_by_name(self.breaker):get_look_horizontal()
 | 
			
		||||
				if math.abs(yaw - yaw2) > 5.8
 | 
			
		||||
				or math.abs(yaw - yaw2) < 0.5 then
 | 
			
		||||
					self.breaking_progress = self.breaking_progress + 1
 | 
			
		||||
				else
 | 
			
		||||
					self.breaking_progress = self.breaking_progress - 1
 | 
			
		||||
				end
 | 
			
		||||
				animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
				if self.breaking_progress < -5
 | 
			
		||||
				or minetest.get_player_by_name(self.breaker):get_player_control().sneak then
 | 
			
		||||
					mob_core.detach(self.driver, {x = 1, y = 0, z = 1})
 | 
			
		||||
					mobkit.lq_idle(self, 0.5, "rear")
 | 
			
		||||
					self.breaking = nil
 | 
			
		||||
					self.breaker = nil
 | 
			
		||||
					self.breaking_progress = nil
 | 
			
		||||
				elseif self.breaking_progress > 5 then
 | 
			
		||||
					mob_core.set_owner(self, self.breaker)
 | 
			
		||||
					self.breaking = nil
 | 
			
		||||
					self.breaker = nil
 | 
			
		||||
					self.breaking_progress = nil
 | 
			
		||||
					local prt_pos = vector.new(pos.x, pos.y + 2, pos.z)
 | 
			
		||||
					local minppos = vector.add(prt_pos, 1)
 | 
			
		||||
					local maxppos = vector.subtract(prt_pos, 1)
 | 
			
		||||
					animalia.particle_spawner(prt_pos, "mob_core_green_particle.png", "float", minppos, maxppos)
 | 
			
		||||
					mobkit.clear_queue_high(self)
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 20
 | 
			
		||||
		and self.driver
 | 
			
		||||
		and not self.breaking then
 | 
			
		||||
			animalia.hq_mount_logic(self, 20)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 5
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 5)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_horse_breed(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
				if self.attention_span < 5 then
 | 
			
		||||
					if mob_core.follow_holding(self, player) then
 | 
			
		||||
						animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
						self.attention_span = self.attention_span + 1
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 12)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("horse", {
 | 
			
		||||
creatura.register_mob("animalia:horse", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 40,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.65, 0, -0.65, 0.65, 1.95, 0.65},
 | 
			
		||||
	visual_size = {x = 10, y = 10},
 | 
			
		||||
	mesh = "animalia_horse.b3d",
 | 
			
		||||
    max_health = 40,
 | 
			
		||||
    armor_groups = {fleshy = 100},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 10,
 | 
			
		||||
	tracking_range = 24,
 | 
			
		||||
    despawn_after = 2000,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	turn_rate = 6,
 | 
			
		||||
	boid_seperation = 1.5,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_horse.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.65,
 | 
			
		||||
		height = 1.95
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 10, y = 10},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_horse_1.png",
 | 
			
		||||
		"animalia_horse_2.png",
 | 
			
		||||
@ -175,29 +88,16 @@ animalia.register_mob("horse", {
 | 
			
		||||
		rear = {range = {x = 120, y = 150}, speed = 27, frame_blend = 0.2, loop = false},
 | 
			
		||||
		rear_constant = {range = {x = 130, y = 140}, speed = 20, frame_blend = 0.3, loop = true}
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 10,
 | 
			
		||||
    max_fall = 8,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
        random = {
 | 
			
		||||
            {
 | 
			
		||||
				name = "animalia_horse_idle_1",
 | 
			
		||||
				gain = 1.0,
 | 
			
		||||
				distance = 8
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				name = "animalia_horse_idle_2",
 | 
			
		||||
				gain = 1.0,
 | 
			
		||||
				distance = 8
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				name = "animalia_horse_idle_3",
 | 
			
		||||
				gain = 1.0,
 | 
			
		||||
				distance = 8
 | 
			
		||||
			}
 | 
			
		||||
        },
 | 
			
		||||
			name = "animalia_horse_idle",
 | 
			
		||||
			gain = 1.0,
 | 
			
		||||
			distance = 8,
 | 
			
		||||
			variations = 3,
 | 
			
		||||
		},
 | 
			
		||||
        hurt = {
 | 
			
		||||
            name = "animalia_horse_hurt",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
@ -209,37 +109,103 @@ animalia.register_mob("horse", {
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:wheat",
 | 
			
		||||
    drops = {
 | 
			
		||||
		{name = "animalia:leather", min = 1, max = 4, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	consumable_nodes = {
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dirt_with_grass",
 | 
			
		||||
			replacement = "default:dirt"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dry_dirt_with_dry_grass",
 | 
			
		||||
			replacement = "default:dry_dirt"
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:leather", chance = 2, min = 1, max = 4},
 | 
			
		||||
	},
 | 
			
		||||
	player_rotation = {x = -60, y = 180, z = 0},
 | 
			
		||||
	driver_scale = {x = 0.1, y = 0.1},
 | 
			
		||||
    driver_attach_at = {x = 0, y = 1.1, z = 0.5},
 | 
			
		||||
	driver_attach_bone = "Torso",
 | 
			
		||||
    driver_eye_offset = {{x = 0, y = 15, z = 0}, {x = 0, y = 15, z = 15}},
 | 
			
		||||
    -- Functions
 | 
			
		||||
	head_data = {
 | 
			
		||||
		bone = "Neck.CTRL",
 | 
			
		||||
		offset = {x = 0, y = 1.98, z = 0},
 | 
			
		||||
		offset = {x = 0, y = 2, z = 0},
 | 
			
		||||
		pitch_correction = 35,
 | 
			
		||||
		pivot_h = 1,
 | 
			
		||||
		pivot_v = 1.5
 | 
			
		||||
	},
 | 
			
		||||
    logic = horse_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = function(self, staticdata, dtime_s)
 | 
			
		||||
		animalia.on_activate(self, staticdata, dtime_s)
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:boid_wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:eat_from_turf",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return math.random(11) * 0.01, {self}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 0.95, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:horse_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[6] = {
 | 
			
		||||
			utility = "animalia:mount",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.rider
 | 
			
		||||
				and self.saddled then
 | 
			
		||||
					return 1, {self, self.rider}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		set_pattern(self)
 | 
			
		||||
		self.saddled = mobkit.recall(self, "saddled") or false
 | 
			
		||||
		self.max_hp = mobkit.recall(self, "max_hp") or random(30, 45)
 | 
			
		||||
		self.speed = mobkit.recall(self, "speed") or random(5, 10)
 | 
			
		||||
		self.jump_power = mobkit.recall(self, "speed") or random(2, 5)
 | 
			
		||||
		self.owner = self:recall("owner") or nil
 | 
			
		||||
		if self.owner then
 | 
			
		||||
			self._despawn = nil
 | 
			
		||||
			self.despawn_after = nil
 | 
			
		||||
		end
 | 
			
		||||
		self.rider = nil
 | 
			
		||||
		self.saddled = self:recall("saddled") or false
 | 
			
		||||
		self.max_health = self:recall("max_health") or random(30, 45)
 | 
			
		||||
		self.speed = self:recall("speed") or random(5, 10)
 | 
			
		||||
		self.jump_power = self:recall("jump_power") or random(2, 5)
 | 
			
		||||
		self:memorize("max_health", self.max_health)
 | 
			
		||||
		self:memorize("speed", self.speed)
 | 
			
		||||
		self:memorize("jump_power", self.jump_power)
 | 
			
		||||
		if self.saddled then
 | 
			
		||||
			local texture = self.object:get_properties().textures[1]
 | 
			
		||||
			self.object:set_properties({
 | 
			
		||||
@ -250,38 +216,95 @@ animalia.register_mob("horse", {
 | 
			
		||||
				{name = "animalia:saddle", chance = 1, min = 1, max = 1}
 | 
			
		||||
			}
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
		if self.breaking
 | 
			
		||||
		and self:timer(1) then
 | 
			
		||||
			local pos = self:get_center_pos()
 | 
			
		||||
			if not minetest.get_player_by_name(self.breaker) then
 | 
			
		||||
				self.breaking = nil
 | 
			
		||||
				self.breaker = nil
 | 
			
		||||
			else
 | 
			
		||||
				local yaw = self.object:get_yaw()
 | 
			
		||||
				local yaw2 = minetest.get_player_by_name(self.breaker):get_look_horizontal()
 | 
			
		||||
				if math.abs(yaw - yaw2) > 5.8
 | 
			
		||||
				or math.abs(yaw - yaw2) < 0.5 then
 | 
			
		||||
					self.breaking_progress = self.breaking_progress + 1
 | 
			
		||||
				else
 | 
			
		||||
					self.breaking_progress = self.breaking_progress - 1
 | 
			
		||||
				end
 | 
			
		||||
				self:initiate_utility("animalia:sporadic_flee", self, puncher, true)
 | 
			
		||||
				if self.breaking_progress < -5
 | 
			
		||||
				or minetest.get_player_by_name(self.breaker):get_player_control().sneak then
 | 
			
		||||
					animalia.mount(self, minetest.get_player_by_name(self.breaker))
 | 
			
		||||
					creatura.action_idle(self, 0.5, "rear")
 | 
			
		||||
					self.breaking = nil
 | 
			
		||||
					self.breaker = nil
 | 
			
		||||
					self.breaking_progress = nil
 | 
			
		||||
				elseif self.breaking_progress > 5 then
 | 
			
		||||
					animalia.mount(self, minetest.get_player_by_name(self.breaker))
 | 
			
		||||
					self.owner = self:memorize("owner", self.breaker)
 | 
			
		||||
					animalia.protect_from_despawn(self)
 | 
			
		||||
					self.breaking = nil
 | 
			
		||||
					self.breaker = nil
 | 
			
		||||
					self.breaking_progress = nil
 | 
			
		||||
					local prt_pos = vector.new(pos.x, pos.y + 2, pos.z)
 | 
			
		||||
					local minppos = vector.add(prt_pos, 1)
 | 
			
		||||
					local maxppos = vector.subtract(prt_pos, 1)
 | 
			
		||||
					animalia.particle_spawner(prt_pos, "creatura_particle_green.png", "float", minppos, maxppos)
 | 
			
		||||
					self:clear_behavior()
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, false)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		if self.tamed
 | 
			
		||||
		local tool_name = clicker:get_wielded_item():get_name()
 | 
			
		||||
		if self.owner
 | 
			
		||||
        and self.owner == clicker:get_player_name() then
 | 
			
		||||
			if self.saddled
 | 
			
		||||
			and tool:get_name() == "" then
 | 
			
		||||
            	mob_core.mount(self, clicker)
 | 
			
		||||
			elseif tool:get_name() == "animalia:saddle" then
 | 
			
		||||
				self.saddled = mobkit.remember(self, "saddled", true)
 | 
			
		||||
			and tool_name == "" then
 | 
			
		||||
				animalia.mount(self, clicker, {rot = {x = -60, y = 180, z = 0}, pos = {x = 0, y = 1.1, z = 0.5}})
 | 
			
		||||
				self:initiate_utility("animalia:mount", self, clicker)
 | 
			
		||||
			elseif tool_name == "animalia:saddle" then
 | 
			
		||||
				self.saddled = self:memorize("saddled", true)
 | 
			
		||||
				local texture = self.object:get_properties().textures[1]
 | 
			
		||||
				self.object:set_properties({
 | 
			
		||||
					textures = {texture .. "^animalia_horse_saddle.png"}
 | 
			
		||||
				})
 | 
			
		||||
				self.drops = {
 | 
			
		||||
					{name = "animalia:leather", chance = 2, min = 1, max = 4},
 | 
			
		||||
					{name = "animalia:saddle", chance = 1, min = 1, max = 1}
 | 
			
		||||
				}
 | 
			
		||||
				tool:take_item()
 | 
			
		||||
				clicker:set_wielded_item(tool)
 | 
			
		||||
			end
 | 
			
		||||
        elseif not self.tamed
 | 
			
		||||
		and tool:get_name() == "" then
 | 
			
		||||
			mob_core.mount(self, clicker)
 | 
			
		||||
        elseif not self.owner
 | 
			
		||||
		and tool_name == "" then
 | 
			
		||||
			animalia.mount(self, clicker, {rot = {x = -60, y = 180, z = 0}, pos = {x = 0, y = 1.1, z = 0.5}})
 | 
			
		||||
			self.breaking = true
 | 
			
		||||
			self.breaker = clicker:get_player_name()
 | 
			
		||||
			self.breaking_progress = 0
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "horse", form = "pg_horse;Horses"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:boid_flee_from_player", self, puncher, true)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:horse", "ebdfd8" ,"653818")
 | 
			
		||||
creatura.register_spawn_egg("animalia:horse", "ebdfd8" ,"653818")
 | 
			
		||||
							
								
								
									
										233
									
								
								mobs/pig.lua
									
									
									
									
									
								
							
							
						
						
									
										233
									
								
								mobs/pig.lua
									
									
									
									
									
								
							@ -2,78 +2,47 @@
 | 
			
		||||
-- Pig --
 | 
			
		||||
---------
 | 
			
		||||
 | 
			
		||||
local function pig_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then	
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 3) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_breed(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
		
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
	        	if self.attention_span < 5 then
 | 
			
		||||
				    if mob_core.follow_holding(self, player) then
 | 
			
		||||
            	        animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
            	        self.attention_span = self.attention_span + 3
 | 
			
		||||
            	    end
 | 
			
		||||
            	end
 | 
			
		||||
			end
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if name:match(":carrot")
 | 
			
		||||
		and (minetest.get_item_group(name, "food") > 0
 | 
			
		||||
		or minetest.get_item_group(name, "food_carrot") > 0) then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 8)
 | 
			
		||||
local destroyable_crops = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
	for name in pairs(minetest.registered_nodes) do
 | 
			
		||||
		if name:match("^crops:")
 | 
			
		||||
		or name:match("^farming:") then
 | 
			
		||||
			table.insert(destroyable_crops, {name = name, replacement = "air"})
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("pig", {
 | 
			
		||||
creatura.register_mob("animalia:pig", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 20,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.35, -0.45, -0.35, 0.35, 0.4, 0.35},
 | 
			
		||||
	visual_size = {x = 11, y = 11},
 | 
			
		||||
	mesh = "animalia_pig.b3d",
 | 
			
		||||
    max_health = 10,
 | 
			
		||||
    armor_groups = {fleshy = 100},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 3,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	turn_rate = 6,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_pig.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.35,
 | 
			
		||||
		height = 0.7
 | 
			
		||||
	},
 | 
			
		||||
	visual_size = {x = 10, y = 10},
 | 
			
		||||
	female_textures = {
 | 
			
		||||
		"animalia_pig_1.png",
 | 
			
		||||
		"animalia_pig_2.png",
 | 
			
		||||
@ -94,71 +63,109 @@ animalia.register_mob("pig", {
 | 
			
		||||
		walk = {range = {x = 1, y = 20}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 1, y = 20}, speed = 45, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 4,
 | 
			
		||||
    max_fall = 3,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
    -- Misc
 | 
			
		||||
	consumable_nodes = destroyable_crops,
 | 
			
		||||
	birth_count = 2,
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_pig_idle",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        },
 | 
			
		||||
        hurt = {
 | 
			
		||||
            name = "animalia_pig_idle",
 | 
			
		||||
            name = "animalia_pig_hurt",
 | 
			
		||||
			gain = 1.0,
 | 
			
		||||
			pitch = 0.5,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        },
 | 
			
		||||
        death = {
 | 
			
		||||
            name = "animalia_pig_death",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
			gain = 1.0,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:carrot"
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:porkchop_raw", min = 1, max = 3, chance = 1}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:eat_from_turf",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if math.random(25) < 2 then
 | 
			
		||||
					return 0.1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:porkchop_raw", chance = 1, min = 1, max = 4}
 | 
			
		||||
	},
 | 
			
		||||
    -- Functions
 | 
			
		||||
    logic = pig_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "pig", form = "pg_pig;Pigs"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:flee_from_player", self, puncher)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:porkchop_raw", {
 | 
			
		||||
	description = "Raw Porkchop",
 | 
			
		||||
	inventory_image = "animalia_porkchop_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:porkchop_cooked", {
 | 
			
		||||
	description = "Cooked Porkchop",
 | 
			
		||||
	inventory_image = "animalia_porkchop_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(7),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:porkchop_raw",
 | 
			
		||||
	output = "animalia:porkchop_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:pig", "e0b1a7" ,"cc9485")
 | 
			
		||||
creatura.register_spawn_egg("animalia:pig", "e0b1a7" ,"cc9485")
 | 
			
		||||
@ -1,151 +1,148 @@
 | 
			
		||||
---------
 | 
			
		||||
-- Cow --
 | 
			
		||||
---------
 | 
			
		||||
--------------
 | 
			
		||||
-- Reindeer --
 | 
			
		||||
--------------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if (name:match(":wheat")
 | 
			
		||||
		or minetest.get_item_group(name, "food_wheat") > 0)
 | 
			
		||||
		and not name:find("seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local random = math.random
 | 
			
		||||
local blend = animalia.frame_blend
 | 
			
		||||
 | 
			
		||||
local function reindeer_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 3) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_breed(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
				if self.attention_span < 5 then
 | 
			
		||||
					if mob_core.follow_holding(self, player) then
 | 
			
		||||
						animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
						self.attention_span = self.attention_span + 1
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 10)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("reindeer", {
 | 
			
		||||
creatura.register_mob("animalia:reindeer", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 20,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.45, 0, -0.45, 0.45, 0.9, 0.45},
 | 
			
		||||
	visual_size = {x = 10, y = 10},
 | 
			
		||||
	mesh = "animalia_reindeer.b3d",
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_reindeer.png",
 | 
			
		||||
	},
 | 
			
		||||
	child_textures = {
 | 
			
		||||
		"animalia_reindeer_calf.png",
 | 
			
		||||
    max_health = 20,
 | 
			
		||||
    armor_groups = {fleshy = 125},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 3,
 | 
			
		||||
	boid_seperation = 1,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_reindeer.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.45,
 | 
			
		||||
		height = 0.9
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 10, y = 10},
 | 
			
		||||
	textures = {"animalia_reindeer.png"},
 | 
			
		||||
	child_textures = {"animalia_reindeer_calf.png"},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 4,
 | 
			
		||||
    max_fall = 3,
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:wheat",
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:venison_raw", min = 1, max = 3, chance = 1},
 | 
			
		||||
		{name = "animalia:leather", min = 1, max = 3, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	consumable_nodes = {
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dirt_with_grass",
 | 
			
		||||
			replacement = "default:dirt"
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dry_dirt_with_dry_grass",
 | 
			
		||||
			replacement = "default:dry_dirt"
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:venison_raw", chance = 1, min = 1, max = 4}
 | 
			
		||||
	},
 | 
			
		||||
    -- Functions
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.7, z = 0},
 | 
			
		||||
		pitch_correction = -45,
 | 
			
		||||
		pivot_h = 1,
 | 
			
		||||
		pivot_v = 1
 | 
			
		||||
	},
 | 
			
		||||
    logic = reindeer_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:boid_wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:eat_from_turf",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if math.random(25) < 2 then
 | 
			
		||||
					return 0.1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "reindeer", form = "pg_reindeer;Reindeer"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:boid_flee_from_player", self, puncher, true)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:venison_raw", {
 | 
			
		||||
	description = "Raw Venison",
 | 
			
		||||
	inventory_image = "animalia_venison_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:venison_cooked", {
 | 
			
		||||
	description = "Venison Steak",
 | 
			
		||||
	inventory_image = "animalia_venison_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(6),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:venison_raw",
 | 
			
		||||
	output = "animalia:venison_cooked",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:reindeer", "8c8174" ,"3d3732")
 | 
			
		||||
creatura.register_spawn_egg("animalia:reindeer", "cac3a1" ,"464438")
 | 
			
		||||
							
								
								
									
										310
									
								
								mobs/sheep.lua
									
									
									
									
									
								
							
							
						
						
									
										310
									
								
								mobs/sheep.lua
									
									
									
									
									
								
							@ -2,6 +2,24 @@
 | 
			
		||||
-- Sheep --
 | 
			
		||||
-----------
 | 
			
		||||
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if (name:match(":wheat")
 | 
			
		||||
		or minetest.get_item_group(name, "food_wheat") > 0)
 | 
			
		||||
		and not name:find("seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local wool_block = "wool:wool"
 | 
			
		||||
 | 
			
		||||
if not minetest.get_modpath("wool") then
 | 
			
		||||
	wool_block = nil
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local creative = minetest.settings:get_bool("creative_mode")
 | 
			
		||||
 | 
			
		||||
local palette  = {
 | 
			
		||||
@ -22,108 +40,38 @@ local palette  = {
 | 
			
		||||
	{"yellow",     "Yellow",     "#e3ff0070"},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
 | 
			
		||||
local min = math.min
 | 
			
		||||
local abs = math.abs
 | 
			
		||||
local random = math.random
 | 
			
		||||
 | 
			
		||||
local function sheep_logic(self)
 | 
			
		||||
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.5, 0.5)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 3) then 
 | 
			
		||||
 | 
			
		||||
		local pos = mobkit.get_stand_pos(self)
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if prty < 5
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 5)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_breed(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
		and self.gotten
 | 
			
		||||
		and math.random(1, 16) == 1 then
 | 
			
		||||
			animalia.hq_eat(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
	        	if self.attention_span < 5 then
 | 
			
		||||
				    if mob_core.follow_holding(self, player) then
 | 
			
		||||
            	        animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
            	        self.attention_span = self.attention_span + 3
 | 
			
		||||
            	    end
 | 
			
		||||
            	end
 | 
			
		||||
			end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 12)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("sheep", {
 | 
			
		||||
creatura.register_mob("animalia:sheep", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 20,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.4, 0, -0.4, 0.4, 0.8, 0.4},
 | 
			
		||||
    max_health = 15,
 | 
			
		||||
    armor_groups = {fleshy = 125},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 3,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_sheep.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.4,
 | 
			
		||||
		height = 0.8
 | 
			
		||||
	},
 | 
			
		||||
	visual_size = {x = 10, y = 10},
 | 
			
		||||
	mesh = "animalia_sheep.b3d",
 | 
			
		||||
	textures = {"animalia_sheep.png^animalia_sheep_wool.png"},
 | 
			
		||||
	child_textures = {"animalia_sheep.png"},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_sheep.png^animalia_sheep_wool.png"
 | 
			
		||||
	},
 | 
			
		||||
	child_textures = {
 | 
			
		||||
		"animalia_sheep.png"
 | 
			
		||||
	},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 4,
 | 
			
		||||
    max_fall = 3,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
	use_texture_alpha = true,
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	sounds = {
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_sheep_idle",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
@ -140,11 +88,11 @@ animalia.register_mob("sheep", {
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:wheat",
 | 
			
		||||
	},
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:mutton_raw", min = 1, max = 3, chance = 1},
 | 
			
		||||
		{name = wool_block, min = 1, max = 3, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	consumable_nodes = {
 | 
			
		||||
		{
 | 
			
		||||
			name = "default:dirt_with_grass",
 | 
			
		||||
@ -155,33 +103,67 @@ animalia.register_mob("sheep", {
 | 
			
		||||
			replacement = "default:dry_dirt"
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:mutton_raw", chance = 1, min = 1, max = 4}
 | 
			
		||||
	},
 | 
			
		||||
    -- Functions
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.41, z = 0},
 | 
			
		||||
		pitch_correction = -45,
 | 
			
		||||
		pivot_h = 0.75,
 | 
			
		||||
		pivot_v = 0.85
 | 
			
		||||
	},
 | 
			
		||||
    logic = sheep_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = function(self, dtime, moveresult)
 | 
			
		||||
		animalia.on_step(self, dtime, moveresult)
 | 
			
		||||
		if mobkit.is_alive(self) then
 | 
			
		||||
			if self.object:get_properties().textures[1] == "animalia_sheep.png"
 | 
			
		||||
			and not self.gotten then
 | 
			
		||||
				self.object:set_properties({
 | 
			
		||||
					textures = {"animalia_sheep.png^animalia_sheep_wool.png"},
 | 
			
		||||
				})
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
	on_activate = function(self, staticdata, dtime_s)
 | 
			
		||||
		animalia.on_activate(self, staticdata, dtime_s)
 | 
			
		||||
		self.dye_color = mobkit.recall(self, "dye_color") or "white"
 | 
			
		||||
		self.dye_hex = mobkit.recall(self, "dye_hex") or ""
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:eat_from_turf",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if math.random(25) < 2 then
 | 
			
		||||
					return 0.1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
        self.gotten = self:recall("gotten") or false
 | 
			
		||||
		self.dye_color = self:recall("dye_color") or "white"
 | 
			
		||||
		self.dye_hex = self:recall("dye_hex") or ""
 | 
			
		||||
		if self.dye_color ~= "white"
 | 
			
		||||
		and not self.gotten then
 | 
			
		||||
			self.object:set_properties({
 | 
			
		||||
@ -193,47 +175,61 @@ animalia.register_mob("sheep", {
 | 
			
		||||
				textures = {"animalia_sheep.png"},
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
	end,
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		local item = clicker:get_wielded_item()
 | 
			
		||||
		local itemname = item:get_name()
 | 
			
		||||
		local name = clicker:get_player_name()
 | 
			
		||||
		if itemname == "animalia:shears"
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		local tool_name = tool:get_name()
 | 
			
		||||
		if tool_name == "animalia:shears"
 | 
			
		||||
		and not self.gotten
 | 
			
		||||
		and not self.child then
 | 
			
		||||
		and self.growth_scale > 0.9 then
 | 
			
		||||
			if not minetest.get_modpath("wool") then
 | 
			
		||||
				return
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local obj = minetest.add_item(
 | 
			
		||||
			minetest.add_item(
 | 
			
		||||
				self.object:get_pos(),
 | 
			
		||||
				ItemStack( "wool:" .. self.dye_color .. " " .. math.random(1, 3) )
 | 
			
		||||
			)
 | 
			
		||||
 | 
			
		||||
			self.gotten = mobkit.remember(self, "gotten", true)
 | 
			
		||||
			self.dye_color = mobkit.remember(self, "dye_color", "white")
 | 
			
		||||
			self.dye_hex = mobkit.remember(self, "dye_hex",  "#abababc000")
 | 
			
		||||
			self.gotten = self:memorize("gotten", true)
 | 
			
		||||
			self.dye_color = self:memorize("dye_color", "white")
 | 
			
		||||
			self.dye_hex = self:memorize("dye_hex",  "#abababc000")
 | 
			
		||||
 | 
			
		||||
			item:add_wear(650) -- 100 uses
 | 
			
		||||
			tool:add_wear(650) -- 100 uses
 | 
			
		||||
 | 
			
		||||
			clicker:set_wielded_item(item)
 | 
			
		||||
			clicker:set_wielded_item(tool)
 | 
			
		||||
 | 
			
		||||
			self.object:set_properties({
 | 
			
		||||
				textures = {"animalia_sheep.png"},
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
		for _, color in ipairs(palette) do
 | 
			
		||||
			if itemname:find("dye:")
 | 
			
		||||
			if tool_name:find("dye:")
 | 
			
		||||
			and not self.gotten
 | 
			
		||||
			and not self.child then
 | 
			
		||||
				local dye = string.split(itemname, ":")[2]
 | 
			
		||||
			and self.growth_scale > 0.9 then
 | 
			
		||||
				local dye = string.split(tool_name, ":")[2]
 | 
			
		||||
				if color[1] == dye then
 | 
			
		||||
 | 
			
		||||
					self.dye_color = mobkit.remember(self, "dye_color", color[1])
 | 
			
		||||
					self.dye_hex = mobkit.remember(self, "dye_hex", color[3])
 | 
			
		||||
					self.dye_color = self:memorize("dye_color", color[1])
 | 
			
		||||
					self.dye_hex = self:memorize("dye_hex", color[3])
 | 
			
		||||
 | 
			
		||||
					self.drops = {
 | 
			
		||||
						{name = "animalia:mutton_raw", chance = 1, min = 1, max = 4},
 | 
			
		||||
@ -245,38 +241,20 @@ animalia.register_mob("sheep", {
 | 
			
		||||
					})
 | 
			
		||||
 | 
			
		||||
					if not creative then
 | 
			
		||||
						item:take_item()
 | 
			
		||||
						clicker:set_wielded_item(item)
 | 
			
		||||
						tool:take_item()
 | 
			
		||||
						clicker:set_wielded_item(tool)
 | 
			
		||||
					end
 | 
			
		||||
					break
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "sheep", form = "pg_sheep;Sheep"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:boid_flee_from_player", self, puncher, true)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b")
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:mutton_raw", {
 | 
			
		||||
	description = "Raw Mutton",
 | 
			
		||||
	inventory_image = "animalia_mutton_raw.png",
 | 
			
		||||
	on_use = minetest.item_eat(1),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:mutton_cooked", {
 | 
			
		||||
	description = "Cooked Mutton",
 | 
			
		||||
	inventory_image = "animalia_mutton_cooked.png",
 | 
			
		||||
	on_use = minetest.item_eat(6),
 | 
			
		||||
	groups = {flammable = 2, meat = 1, food_meat = 1},
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	type  =  "cooking",
 | 
			
		||||
	recipe  = "animalia:mutton_raw",
 | 
			
		||||
	output = "animalia:mutton_cooked",
 | 
			
		||||
})
 | 
			
		||||
creatura.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b")
 | 
			
		||||
							
								
								
									
										89
									
								
								mobs/tropical_fish.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								mobs/tropical_fish.lua
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
			
		||||
----------
 | 
			
		||||
-- Fish --
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
creatura.register_mob("animalia:tropical_fish", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 5,
 | 
			
		||||
    armor_groups = {fleshy = 150},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 2,
 | 
			
		||||
	tracking_range = 6,
 | 
			
		||||
    despawn_after = 2500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 0.1,
 | 
			
		||||
	max_fall = 8,
 | 
			
		||||
	turn_rate = 8,
 | 
			
		||||
	boid_seperation = 0.3,
 | 
			
		||||
	bouyancy_multiplier = 0,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_clownfish.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.15,
 | 
			
		||||
		height = 0.3
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	textures = {
 | 
			
		||||
		"animalia_clownfish.png",
 | 
			
		||||
		"animalia_blue_tang.png",
 | 
			
		||||
		"animalia_angelfish.png"
 | 
			
		||||
	},
 | 
			
		||||
    animations = {
 | 
			
		||||
		swim = {range = {x = 1, y = 20}, speed = 20, frame_blend = 0.3, loop = true},
 | 
			
		||||
		flop = {range = {x = 30, y = 40}, speed = 20, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	makes_footstep_sound = false,
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:schooling",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:flop",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.in_liquid then
 | 
			
		||||
					self:hurt(1)
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
		if self.texture_no == 3 then
 | 
			
		||||
			self.object:set_properties({
 | 
			
		||||
				mesh = "animalia_angelfish.b3d",
 | 
			
		||||
			})
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "tropical_fish", form = "pg_tropical_fish;Tropical Fish"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_spawn_egg("animalia:tropical_fish", "e28821", "f6e5d2")
 | 
			
		||||
 | 
			
		||||
animalia.alias_mob("animalia:clownfish", "animalia:tropical_fish")
 | 
			
		||||
animalia.alias_mob("animalia:blue_tang", "animalia:tropical_fish")
 | 
			
		||||
animalia.alias_mob("animalia:angelfish", "animalia:tropical_fish")
 | 
			
		||||
							
								
								
									
										216
									
								
								mobs/turkey.lua
									
									
									
									
									
								
							
							
						
						
									
										216
									
								
								mobs/turkey.lua
									
									
									
									
									
								
							@ -2,83 +2,35 @@
 | 
			
		||||
-- Turkey --
 | 
			
		||||
------------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
local follows = {}
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
 | 
			
		||||
local function turkey_logic(self)
 | 
			
		||||
 | 
			
		||||
	if self.hp <= 0 then
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if self.status ~= "following" then
 | 
			
		||||
		if self.attention_span > 1 then
 | 
			
		||||
			self.attention_span = self.attention_span - self.dtime
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		self.attention_span = self.attention_span + self.dtime
 | 
			
		||||
		mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.45, 0.25)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 3) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 14)
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 3
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_fowl_breed(self, 3)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 2
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 2 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 2, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
	        	if self.attention_span < 5 then
 | 
			
		||||
				    if mob_core.follow_holding(self, player) then
 | 
			
		||||
            	        animalia.hq_follow_player(self, 2, player)
 | 
			
		||||
            	        self.attention_span = self.attention_span + 3
 | 
			
		||||
            	    end
 | 
			
		||||
            	end
 | 
			
		||||
			end
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
    for name, def in pairs(minetest.registered_items) do
 | 
			
		||||
        if name:match(":seed_")
 | 
			
		||||
		or name:match("_seed") then
 | 
			
		||||
			table.insert(follows, name)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 8)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("turkey", {
 | 
			
		||||
	-- Stats
 | 
			
		||||
	health = 15,
 | 
			
		||||
	fleshy = 100,
 | 
			
		||||
	view_range = 26,
 | 
			
		||||
	lung_capacity = 10,
 | 
			
		||||
	-- Visual
 | 
			
		||||
	collisionbox = {-0.3, -0.2, -0.3, 0.3, 0.4, 0.3},
 | 
			
		||||
	visual_size = {x = 7, y = 7},
 | 
			
		||||
	mesh = "animalia_turkey.b3d",
 | 
			
		||||
creatura.register_mob("animalia:turkey", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    max_health = 10,
 | 
			
		||||
    armor_groups = {fleshy = 150},
 | 
			
		||||
    damage = 0,
 | 
			
		||||
    speed = 4,
 | 
			
		||||
	tracking_range = 16,
 | 
			
		||||
    despawn_after = 1500,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 8,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_turkey.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.3,
 | 
			
		||||
		height = 0.6
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 7, y = 7},
 | 
			
		||||
	female_textures = {"animalia_turkey_hen.png"},
 | 
			
		||||
	male_textures = {"animalia_turkey_tom.png"},
 | 
			
		||||
	child_textures = {"animalia_turkey_chick.png"},
 | 
			
		||||
@ -88,12 +40,9 @@ animalia.register_mob("turkey", {
 | 
			
		||||
		run = {range = {x = 40, y = 60}, speed = 45, frame_blend = 0.3, loop = true},
 | 
			
		||||
        fall = {range = {x = 70, y = 90}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
	},
 | 
			
		||||
	-- Physics
 | 
			
		||||
	speed = 5,
 | 
			
		||||
	max_fall = 6,
 | 
			
		||||
	-- Attributes
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_turkey_idle",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
@ -110,37 +59,96 @@ animalia.register_mob("turkey", {
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
    },
 | 
			
		||||
	-- Behavior
 | 
			
		||||
	defend_owner = false,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"farming:seed_cotton",
 | 
			
		||||
		"farming:seed_wheat"
 | 
			
		||||
	},
 | 
			
		||||
	drops = {
 | 
			
		||||
		{name = "animalia:feather", chance = 1, min = 1, max = 2},
 | 
			
		||||
		{name = "animalia:poultry_raw", chance = 1, min = 2, max = 5}
 | 
			
		||||
	},
 | 
			
		||||
	-- Functions
 | 
			
		||||
    drops = {
 | 
			
		||||
        {name = "animalia:poultry_raw", min = 2, max = 4, chance = 1},
 | 
			
		||||
		{name = "animalia:feather", min = 2, max = 4, chance = 2}
 | 
			
		||||
    },
 | 
			
		||||
    follow = follows,
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.15, z = 0},
 | 
			
		||||
		pitch_correction = 45,
 | 
			
		||||
		pivot_h = 0.45,
 | 
			
		||||
		pivot_v = 0.65
 | 
			
		||||
	},
 | 
			
		||||
	physics = animalia.lightweight_physics,
 | 
			
		||||
	logic = turkey_logic,
 | 
			
		||||
	get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
    on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, 1, false, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, true)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.hq_sporadic_flee(self, 10)
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:resist_fall",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.touching_ground then
 | 
			
		||||
					return 0.11, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 1, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.8, {self, self.lasso_origin, true}
 | 
			
		||||
				end
 | 
			
		||||
				local player = creatura.get_nearby_player(self)
 | 
			
		||||
				if player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.8, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:bird_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self.attention_span = 8
 | 
			
		||||
        self._path = {}
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.75, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "turkey", form = "pg_turkey;Turkeys"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		self:initiate_utility("animalia:flee_from_player", self, puncher)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:turkey", "352b22", "2f2721")
 | 
			
		||||
creatura.register_spawn_egg("animalia:turkey", "352b22", "2f2721")
 | 
			
		||||
							
								
								
									
										400
									
								
								mobs/wolf.lua
									
									
									
									
									
								
							
							
						
						
									
										400
									
								
								mobs/wolf.lua
									
									
									
									
									
								
							@ -2,9 +2,7 @@
 | 
			
		||||
-- Wolf --
 | 
			
		||||
----------
 | 
			
		||||
 | 
			
		||||
local clamp_bone_rot = animalia.clamp_bone_rot
 | 
			
		||||
 | 
			
		||||
local interp = animalia.interp
 | 
			
		||||
local vec_dist = vector.distance
 | 
			
		||||
 | 
			
		||||
local follow = {
 | 
			
		||||
	"animalia:mutton_raw",
 | 
			
		||||
@ -23,203 +21,239 @@ if minetest.registered_items["bonemeal:bone"] then
 | 
			
		||||
	}
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.bh_attack(self, prty, target)
 | 
			
		||||
	if mobkit.is_alive(target) then
 | 
			
		||||
		if target:is_player() then
 | 
			
		||||
			if not self.tamed
 | 
			
		||||
			or target:get_player_name() ~= self.owner then
 | 
			
		||||
				animalia.hq_attack(self, prty, target)
 | 
			
		||||
			end
 | 
			
		||||
		elseif target:get_luaentity() then
 | 
			
		||||
			if not self.tamed
 | 
			
		||||
			or not mob_core.shared_owner(self, target) then
 | 
			
		||||
				animalia.hq_attack(self, prty, target)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
local function is_value_in_table(tbl, val)
 | 
			
		||||
    for _, v in pairs(tbl) do
 | 
			
		||||
        if v == val then
 | 
			
		||||
            return true
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function wolf_logic(self)
 | 
			
		||||
	
 | 
			
		||||
	if self.hp <= 0 then	
 | 
			
		||||
		mob_core.on_die(self)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	animalia.head_tracking(self, 0.5, 0.75)
 | 
			
		||||
 | 
			
		||||
	if mobkit.timer(self, 1) then
 | 
			
		||||
 | 
			
		||||
		local prty = mobkit.get_queue_priority(self)
 | 
			
		||||
		local player = mobkit.get_nearby_player(self)
 | 
			
		||||
 | 
			
		||||
		mob_core.random_sound(self, 22)
 | 
			
		||||
		mob_core.growth(self)
 | 
			
		||||
 | 
			
		||||
		if self.status ~= "following" then
 | 
			
		||||
            if self.attention_span > 1 then
 | 
			
		||||
                self.attention_span = self.attention_span - 1
 | 
			
		||||
                mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
            end
 | 
			
		||||
		else
 | 
			
		||||
			self.attention_span = self.attention_span + 1
 | 
			
		||||
			mobkit.remember(self, "attention_span", self.attention_span)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 22
 | 
			
		||||
		and self.order == "sit" then
 | 
			
		||||
			if not mobkit.is_queue_empty_high(self) then
 | 
			
		||||
				mobkit.clear_queue_high(self)
 | 
			
		||||
			end
 | 
			
		||||
			mobkit.animate(self, "sit")
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 21
 | 
			
		||||
		and self.owner_target then
 | 
			
		||||
			if not mob_core.shared_owner(self, self.owner_target) then
 | 
			
		||||
            	animalia.hq_attack(self, 21, self.owner_target)
 | 
			
		||||
			end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
		if prty < 20
 | 
			
		||||
		and self.order == "follow"
 | 
			
		||||
		and self.owner
 | 
			
		||||
		and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
			local owner = minetest.get_player_by_name(self.owner)
 | 
			
		||||
			animalia.hq_follow_player(self, 20, owner, true)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 5
 | 
			
		||||
		and self.isinliquid then
 | 
			
		||||
			animalia.hq_go_to_land(self, 5)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty < 4
 | 
			
		||||
        and self.breeding then
 | 
			
		||||
            animalia.hq_breed(self, 4)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if prty == 3
 | 
			
		||||
		and not self.lasso_player
 | 
			
		||||
		and (not player
 | 
			
		||||
		or not mob_core.follow_holding(self, player)) then
 | 
			
		||||
			mobkit.clear_queue_high(self)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
        if prty < 3 then
 | 
			
		||||
			if self.caught_with_lasso
 | 
			
		||||
			and self.lasso_player then
 | 
			
		||||
				animalia.hq_follow_player(self, 3, self.lasso_player, true)
 | 
			
		||||
			elseif player then
 | 
			
		||||
	        	if self.attention_span < 5 then
 | 
			
		||||
				    if mob_core.follow_holding(self, player) then
 | 
			
		||||
            	        animalia.hq_follow_player(self, 3, player)
 | 
			
		||||
            	        self.attention_span = self.attention_span + 3
 | 
			
		||||
            	    end
 | 
			
		||||
            	end
 | 
			
		||||
			end
 | 
			
		||||
        end
 | 
			
		||||
		
 | 
			
		||||
		if prty < 2 then
 | 
			
		||||
			local target = mobkit.get_closest_entity(self, "animalia:sheep")
 | 
			
		||||
			if target then
 | 
			
		||||
				animalia.bh_attack(self, 2, target)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		if mobkit.is_queue_empty_high(self) then
 | 
			
		||||
			animalia.hq_wander_group(self, 0, 8)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
animalia.register_mob("wolf", {
 | 
			
		||||
creatura.register_mob("animalia:wolf", {
 | 
			
		||||
    -- Stats
 | 
			
		||||
    health = 25,
 | 
			
		||||
    fleshy = 100,
 | 
			
		||||
    view_range = 32,
 | 
			
		||||
    lung_capacity = 10,
 | 
			
		||||
    -- Visual
 | 
			
		||||
	collisionbox = {-0.35, -0.375, -0.35, 0.35, 0.4, 0.35},
 | 
			
		||||
	visual_size = {x = 9, y = 9},
 | 
			
		||||
	scale_stage1 = 0.5,
 | 
			
		||||
    scale_stage2 = 0.65,
 | 
			
		||||
    scale_stage3 = 0.80,
 | 
			
		||||
	mesh = "animalia_wolf.b3d",
 | 
			
		||||
    max_health = 15,
 | 
			
		||||
    armor_groups = {fleshy = 100},
 | 
			
		||||
    damage = 4,
 | 
			
		||||
    speed = 5,
 | 
			
		||||
	tracking_range = 32,
 | 
			
		||||
    despawn_after = 2000,
 | 
			
		||||
	-- Entity Physics
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_wolf.b3d",
 | 
			
		||||
	hitbox = {
 | 
			
		||||
		width = 0.35,
 | 
			
		||||
		height = 0.7
 | 
			
		||||
	},
 | 
			
		||||
    visual_size = {x = 9, y = 9},
 | 
			
		||||
	textures = {"animalia_wolf.png"},
 | 
			
		||||
	animations = {
 | 
			
		||||
		stand = {range = {x = 30, y = 49}, speed = 10, frame_blend = 0.3, loop = true},
 | 
			
		||||
		sit = {range = {x = 60, y = 90}, speed = 20, frame_blend = 0.3, loop = true},
 | 
			
		||||
		walk = {range = {x = 1, y = 20}, speed = 30, frame_blend = 0.3, loop = true},
 | 
			
		||||
		run = {range = {x = 1, y = 20}, speed = 45, frame_blend = 0.3, loop = true},
 | 
			
		||||
		leap = {range = {x = 100, y = 100}, speed = 1, frame_blend = 0.15, loop = false}
 | 
			
		||||
	},
 | 
			
		||||
    -- Physics
 | 
			
		||||
    speed = 8,
 | 
			
		||||
    max_fall = 4,
 | 
			
		||||
    -- Attributes
 | 
			
		||||
    sounds = {
 | 
			
		||||
        alter_child_pitch = true,
 | 
			
		||||
        random = {
 | 
			
		||||
            name = "animalia_wolf_idle",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        },
 | 
			
		||||
        hurt = {
 | 
			
		||||
            name = "animalia_wolf_hurt",
 | 
			
		||||
			gain = 1.0,
 | 
			
		||||
			pitch = 0.5,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        },
 | 
			
		||||
        death = {
 | 
			
		||||
            name = "animalia_wolf_death",
 | 
			
		||||
            gain = 1.0,
 | 
			
		||||
            distance = 8
 | 
			
		||||
        }
 | 
			
		||||
	},
 | 
			
		||||
	reach = 2,
 | 
			
		||||
    damage = 3,
 | 
			
		||||
    knockback = 2,
 | 
			
		||||
    punch_cooldown = 1,
 | 
			
		||||
    -- Behavior
 | 
			
		||||
    defend_owner = true,
 | 
			
		||||
	follow = {
 | 
			
		||||
		"bonemeal:bone",
 | 
			
		||||
		"animalia:beef_raw",
 | 
			
		||||
		"animalia:porkchop_raw",
 | 
			
		||||
		"animalia:mutton_raw",
 | 
			
		||||
		"animalia:poultry_raw"
 | 
			
		||||
	},
 | 
			
		||||
    -- Functions
 | 
			
		||||
    -- Misc
 | 
			
		||||
	catch_with_net = true,
 | 
			
		||||
	assist_owner = true,
 | 
			
		||||
    follow = follow,
 | 
			
		||||
	head_data = {
 | 
			
		||||
		offset = {x = 0, y = 0.22, z = 0},
 | 
			
		||||
		pitch_correction = -20,
 | 
			
		||||
		pitch_correction = -25,
 | 
			
		||||
		pivot_h = 0.65,
 | 
			
		||||
		pivot_v = 0.65
 | 
			
		||||
	},
 | 
			
		||||
    logic = wolf_logic,
 | 
			
		||||
    get_staticdata = mobkit.statfunc,
 | 
			
		||||
	on_step = animalia.on_step,
 | 
			
		||||
	on_activate = animalia.on_activate,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.feed_tame(self, clicker, math.random(3, 5), true, true) then return end
 | 
			
		||||
		mob_core.protect(self, clicker, false)
 | 
			
		||||
		mob_core.nametag(self, clicker, true)
 | 
			
		||||
		if not self.owner
 | 
			
		||||
		or clicker:get_player_name() ~= self.owner then return end
 | 
			
		||||
		if self.order == "wander" then
 | 
			
		||||
			self.order = "follow"
 | 
			
		||||
		elseif self.order == "follow" then
 | 
			
		||||
			self.order = "sit"
 | 
			
		||||
		else
 | 
			
		||||
			self.order = "wander"
 | 
			
		||||
    -- Function
 | 
			
		||||
	utility_stack = {
 | 
			
		||||
		[1] = {
 | 
			
		||||
			utility = "animalia:wander",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				return 0.1, {self, true}
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[2] = {
 | 
			
		||||
			utility = "animalia:swim_to_land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.in_liquid then
 | 
			
		||||
					return 0.9, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[3] = {
 | 
			
		||||
			utility = "animalia:attack",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local target = creatura.get_nearby_entity(self, "animalia:sheep")
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				local is_attacking = self:get_utility() == "animalia:attack"
 | 
			
		||||
				if player then
 | 
			
		||||
					if is_value_in_table(self.enemies, player:get_player_name()) then
 | 
			
		||||
						local nearby_players = creatura.get_nearby_players(self)
 | 
			
		||||
						local nearby_allies = creatura.get_nearby_entities(self, self.name)
 | 
			
		||||
						if #nearby_players < #nearby_allies then
 | 
			
		||||
							target = player
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				if target then
 | 
			
		||||
					if is_attacking
 | 
			
		||||
					and self._utility_data.args[2] == target then
 | 
			
		||||
						return 0
 | 
			
		||||
					end
 | 
			
		||||
					return 0.85, {self, target}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[4] = {
 | 
			
		||||
			utility = "animalia:flee_from_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player then
 | 
			
		||||
					if is_value_in_table(self.enemies, player:get_player_name()) then
 | 
			
		||||
						local nearby_players = creatura.get_nearby_players(self)
 | 
			
		||||
						local nearby_allies =  creatura.get_nearby_entities(self, self.name)
 | 
			
		||||
						if #nearby_players >= #nearby_allies then
 | 
			
		||||
							return 0.86, {self, player}
 | 
			
		||||
						end
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[5] = {
 | 
			
		||||
			utility = "animalia:sit",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.order == "sit" then
 | 
			
		||||
					return 0.8, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[6] = {
 | 
			
		||||
			utility = "animalia:follow_player",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				local trust = 0
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if self.lasso_origin
 | 
			
		||||
				and type(self.lasso_origin) == "userdata" then
 | 
			
		||||
					return 0.7, {self, self.lasso_origin, true}
 | 
			
		||||
				elseif player
 | 
			
		||||
				and self:follow_wielded_item(player) then
 | 
			
		||||
					return 0.7, {self, player}
 | 
			
		||||
				end
 | 
			
		||||
				if self.order == "follow"
 | 
			
		||||
				and self.owner
 | 
			
		||||
				and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
					return 1, {self, minetest.get_player_by_name(self.owner), true}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		[7] = {
 | 
			
		||||
			utility = "animalia:mammal_breed",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if self.breeding then
 | 
			
		||||
					return 0.7, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		self.order = self:recall("order") or "wander"
 | 
			
		||||
		self.owner = self:recall("owner") or nil
 | 
			
		||||
		self.enemies = self:recall("enemies") or {}
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and minetest.get_player_by_name(self.owner) then
 | 
			
		||||
			if not is_value_in_table(animalia.pets[self.owner], self.object) then
 | 
			
		||||
				table.insert(animalia.pets[self.owner], self.object)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		mobkit.remember(self, "order", self.order)
 | 
			
		||||
    end,
 | 
			
		||||
    step_func = function(self)
 | 
			
		||||
		animalia.step_timers(self)
 | 
			
		||||
		animalia.head_tracking(self, 0.5, 0.75)
 | 
			
		||||
		animalia.do_growth(self, 60)
 | 
			
		||||
		animalia.update_lasso_effects(self)
 | 
			
		||||
    end,
 | 
			
		||||
    death_func = function(self)
 | 
			
		||||
		if self:get_utility() ~= "animalia:die" then
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if not clicker:is_player() then return end
 | 
			
		||||
		local passive = true
 | 
			
		||||
		if is_value_in_table(self.enemies, clicker:get_player_name()) then
 | 
			
		||||
			passive = false
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.feed(self, clicker, passive, passive) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and clicker:get_player_name() == self.owner
 | 
			
		||||
		and clicker:get_player_control().sneak then
 | 
			
		||||
			local order = self.order
 | 
			
		||||
			if order == "wander" then
 | 
			
		||||
				minetest.chat_send_player(clicker:get_player_name(), "Wolf is following")
 | 
			
		||||
				self.order = "follow"
 | 
			
		||||
				self:initiate_utility("animalia:follow_player", self, clicker, true)
 | 
			
		||||
				self:set_utility_score(1)
 | 
			
		||||
			elseif order == "follow" then
 | 
			
		||||
				minetest.chat_send_player(clicker:get_player_name(), "Wolf is sitting")
 | 
			
		||||
				self.order = "sit"
 | 
			
		||||
				self:initiate_utility("animalia:sit", self)
 | 
			
		||||
				self:set_utility_score(0.8)
 | 
			
		||||
			else
 | 
			
		||||
				minetest.chat_send_player(clicker:get_player_name(), "Wolf is wandering")
 | 
			
		||||
				self.order = "wander"
 | 
			
		||||
				self:set_utility_score(0)
 | 
			
		||||
			end
 | 
			
		||||
			self:memorize("order", self.order)
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "wolf", form = "pg_wolf;Wolves"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, _, tool_capabilities, dir)
 | 
			
		||||
		mob_core.on_punch_basic(self, puncher, tool_capabilities, dir)
 | 
			
		||||
		animalia.bh_attack(self, 10, puncher)
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
		if puncher:is_player() then
 | 
			
		||||
			if self.owner
 | 
			
		||||
			and puncher:get_player_name() == self.owner then
 | 
			
		||||
				return
 | 
			
		||||
			elseif not is_value_in_table(self.enemies, puncher:get_player_name()) then
 | 
			
		||||
				table.insert(self.enemies, puncher:get_player_name())
 | 
			
		||||
				if #self.enemies > 15 then
 | 
			
		||||
					table.remove(self.enemies, 1)
 | 
			
		||||
				end
 | 
			
		||||
				self.enemies = self:memorize("enemies", self.enemies)
 | 
			
		||||
			else
 | 
			
		||||
				table.remove(self.enemies, 1)
 | 
			
		||||
				table.insert(self.enemies, puncher:get_player_name())
 | 
			
		||||
				self.enemies = self:memorize("enemies", self.enemies)
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		self:initiate_utility("animalia:attack", self, puncher, true)
 | 
			
		||||
		self:set_utility_score(1)
 | 
			
		||||
	end,
 | 
			
		||||
	deactivate_func = function(self)
 | 
			
		||||
		if self.owner then
 | 
			
		||||
			for i = 1, #animalia.pets[self.owner] do
 | 
			
		||||
				if animalia.pets[self.owner][i] == self.object then
 | 
			
		||||
					animalia.pets[self.owner][i] = nil
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
		if self.enemies
 | 
			
		||||
		and self.enemies[1] then
 | 
			
		||||
			self.enemies[1] = nil
 | 
			
		||||
			self.enemies = self:memorize("enemies", self.enemies)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
mob_core.register_spawn_egg("animalia:wolf", "a19678" ,"231b13")
 | 
			
		||||
creatura.register_spawn_egg("animalia:wolf", "a19678" ,"231b13")
 | 
			
		||||
							
								
								
									
										6
									
								
								mod.conf
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								mod.conf
									
									
									
									
									
								
							@ -1,4 +1,4 @@
 | 
			
		||||
name = animalia
 | 
			
		||||
depends = mobkit, mob_core
 | 
			
		||||
optional_depends = default
 | 
			
		||||
description = Adds useful Animals for food, ambiance, and more
 | 
			
		||||
depends = creatura
 | 
			
		||||
optional_depends = default, mcl_player
 | 
			
		||||
description = Adds unique and consistantly designed Animals
 | 
			
		||||
 | 
			
		||||
@ -1,17 +1,17 @@
 | 
			
		||||
#    How many chunks can generate before adding another to spawn queue
 | 
			
		||||
chunk_spawn_add_int (Chunk Spawning Addition Interval) float 64
 | 
			
		||||
chunk_spawn_add_int (Chunk Spawning Addition Interval) float 6
 | 
			
		||||
 | 
			
		||||
#    How often (in seconds) the spawn queue is executed and cleared
 | 
			
		||||
chunk_spawn_queue_int (Chunk Spawning Queue Execution Interval) float 16
 | 
			
		||||
 | 
			
		||||
#    How often (in seconds) mob spawns are attempted (higher number means less spawning)
 | 
			
		||||
animalia_spawn_int (Spawn Interval) float 60
 | 
			
		||||
 | 
			
		||||
#    If true, mobs will spawn in the wild
 | 
			
		||||
spawn_mobs (Spawn Mobs) bool true
 | 
			
		||||
 | 
			
		||||
#    If true, items from mobs_redo and mobs_animal will be converted to Animalia items
 | 
			
		||||
convert_redo_items (Convert Mobs Redo Items) bool false
 | 
			
		||||
convert_redo_items(Convert Mobs Redo Items) bool false
 | 
			
		||||
 | 
			
		||||
#    If true, mobs will do a small hop to step up blocks
 | 
			
		||||
animalia_fancy_step (Fancy Stepping) bool true
 | 
			
		||||
#    If true, Guano will accumulate under resting bats
 | 
			
		||||
guano_accumulation (Guano Accumulation) bool true
 | 
			
		||||
 | 
			
		||||
#    If true, Guano can be used as fertilizer
 | 
			
		||||
guano_fertilization (Guano Fertilization) bool true
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user