Add Nests, Add Nametags, Improve Bird behavior, Improve Boids, Fix crashes, Fix Bird Libri entry
							
								
								
									
										38
									
								
								api/api.lua
									
									
									
									
									
								
							
							
						
						@ -160,6 +160,15 @@ end
 | 
			
		||||
-- Mob Functions --
 | 
			
		||||
-------------------
 | 
			
		||||
 | 
			
		||||
local function activate_nametag(self)
 | 
			
		||||
    self.nametag = self:recall("nametag") or nil
 | 
			
		||||
    if not self.nametag then return end
 | 
			
		||||
    self.object:set_properties({
 | 
			
		||||
        nametag = self.nametag,
 | 
			
		||||
        nametag_color = "#FFFFFF"
 | 
			
		||||
    })
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.initialize_api(self)
 | 
			
		||||
    self.gender = self:recall("gender") or nil
 | 
			
		||||
    if not self.gender then
 | 
			
		||||
@ -170,6 +179,7 @@ function animalia.initialize_api(self)
 | 
			
		||||
    self.gotten = self:recall("gotten") or false
 | 
			
		||||
    self.breeding = false
 | 
			
		||||
    self.breeding_cooldown = self:recall("breeding_cooldown") or 0
 | 
			
		||||
    activate_nametag(self)
 | 
			
		||||
    if self.growth_scale then
 | 
			
		||||
        self:memorize("growth_scale", self.growth_scale) -- This is for spawning children
 | 
			
		||||
    end
 | 
			
		||||
@ -194,7 +204,7 @@ function animalia.initialize_api(self)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.step_timers(self)
 | 
			
		||||
    self.breeding_cooldown = self.breeding_cooldown - self.dtime
 | 
			
		||||
    self.breeding_cooldown = (self.breeding_cooldown or 30) - self.dtime
 | 
			
		||||
    if self.breeding
 | 
			
		||||
    and self.breeding_cooldown <= 30 then
 | 
			
		||||
        self.breeding = false
 | 
			
		||||
@ -234,6 +244,27 @@ function animalia.do_growth(self, interval)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function animalia.set_nametag(self, clicker)
 | 
			
		||||
    local item = clicker:get_wielded_item()
 | 
			
		||||
    if item
 | 
			
		||||
    and item:get_name() ~= "animalia:nametag" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
    local name = item:get_meta():get_string("name")
 | 
			
		||||
    if not name
 | 
			
		||||
    or name == "" then
 | 
			
		||||
        return
 | 
			
		||||
    end
 | 
			
		||||
    self.nametag = self:memorize("nametag", name)
 | 
			
		||||
    self.despawn_after = self:memorize("despawn_after", nil)
 | 
			
		||||
    activate_nametag(self)
 | 
			
		||||
    if not creative then
 | 
			
		||||
        item:take_item()
 | 
			
		||||
        clicker:set_wielded_item(item)
 | 
			
		||||
    end
 | 
			
		||||
    return true
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-----------------------
 | 
			
		||||
-- Dynamic Animation --
 | 
			
		||||
-----------------------
 | 
			
		||||
@ -815,7 +846,8 @@ local libri_animal_info = {
 | 
			
		||||
                "deserts or tundras. They fly in ",
 | 
			
		||||
                "flocks that vary in size from 4 ",
 | 
			
		||||
                "or 5 individuals to large flocks ",
 | 
			
		||||
                "exceeding a dozen individuals. Their calls vary between ",
 | 
			
		||||
                "exceeding a dozen individuals. ",
 | 
			
		||||
                "Their calls vary between ",
 | 
			
		||||
                "species, making it easy to tell ",
 | 
			
		||||
                "what kind of birds are around."
 | 
			
		||||
            }
 | 
			
		||||
@ -1123,7 +1155,7 @@ local function get_libri_page(mob_name, player_name)
 | 
			
		||||
        -- Background
 | 
			
		||||
        "formspec_version[3]",
 | 
			
		||||
        "size[16,10]",
 | 
			
		||||
        "background[-0.7,-0.5;17.5,11.5;animalia_libri_bg_v2.png]",
 | 
			
		||||
        "background[-0.7,-0.5;17.5,11.5;animalia_libri_bg.png]",
 | 
			
		||||
        "image[-0.7,-0.5;17.5,11.5;animalia_libri_info_fg.png]",
 | 
			
		||||
        -- Mesh
 | 
			
		||||
        "model[1.5,1.5;5,5;libri_mesh;" .. mesh .. ";" .. texture .. ";-30,225;false;false;0,0;0]",
 | 
			
		||||
 | 
			
		||||
@ -77,6 +77,7 @@ end)
 | 
			
		||||
 | 
			
		||||
local moveable = creatura.is_pos_moveable
 | 
			
		||||
local fast_ray_sight = creatura.fast_ray_sight
 | 
			
		||||
local get_node_def = creatura.get_node_def
 | 
			
		||||
 | 
			
		||||
local function get_ground_level(pos2, max_height)
 | 
			
		||||
    local node = minetest.get_node(pos2)
 | 
			
		||||
@ -458,24 +459,25 @@ function animalia.action_boid_move(self, pos2, timeout, method)
 | 
			
		||||
        if #boids > 2 then
 | 
			
		||||
            local boid_angle, boid_lift = creatura.get_boid_angle(self, boids, 6)
 | 
			
		||||
            if boid_angle then
 | 
			
		||||
                local dir2goal = vec_dir(pos, pos2)
 | 
			
		||||
                local dir2goal = vec_dir(pos, goal)
 | 
			
		||||
                local yaw2goal = minetest.dir_to_yaw(dir2goal)
 | 
			
		||||
                boid_angle = boid_angle + (yaw2goal - boid_angle) * 0.15
 | 
			
		||||
                boid_angle = boid_angle + (yaw2goal - boid_angle) * 0.25
 | 
			
		||||
                local boid_dir = minetest.yaw_to_dir(boid_angle)
 | 
			
		||||
                if boid_lift then
 | 
			
		||||
                    boid_dir.y = boid_lift + (vec_dir(pos, goal).y - boid_lift) * 0.5
 | 
			
		||||
                    boid_dir.y = boid_lift + (vec_dir(pos, goal).y - boid_lift) * 0.25
 | 
			
		||||
                else
 | 
			
		||||
                    boid_dir.y = vec_dir(pos, goal).y
 | 
			
		||||
                end
 | 
			
		||||
                pos2 = vec_add(pos, vec_multi(boid_dir, 4))
 | 
			
		||||
                boid_dir = vector.normalize(boid_dir)
 | 
			
		||||
                goal = vec_add(pos, vec_multi(boid_dir, vec_dist(pos, goal)))
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        if timer <= 0
 | 
			
		||||
        or self:pos_in_box(pos2, 0.25) then
 | 
			
		||||
        or self:pos_in_box(goal, 0.5) then
 | 
			
		||||
            self:halt()
 | 
			
		||||
            return true
 | 
			
		||||
        end
 | 
			
		||||
        self:move(pos2, method or "animalia:fly_obstacle_avoidance", 1)
 | 
			
		||||
        self:move(goal, method or "animalia:fly_obstacle_avoidance", 1)
 | 
			
		||||
    end
 | 
			
		||||
    self:set_action(func)
 | 
			
		||||
end
 | 
			
		||||
@ -1261,7 +1263,7 @@ creatura.register_utility("animalia:aerial_flock", function(self, scale)
 | 
			
		||||
    local function func(self)
 | 
			
		||||
        if self:timer(2)
 | 
			
		||||
        and self.stamina <= 0 then
 | 
			
		||||
            local boids = creatura.get_boid_members(self.object:get_pos(), 6, self.name)
 | 
			
		||||
            local boids = get_boid_members(self.object:get_pos(), 6, self.name, self.texture_no)
 | 
			
		||||
            if #boids > 1 then
 | 
			
		||||
                for i = 1, #boids do
 | 
			
		||||
                    local boid = boids[i]
 | 
			
		||||
@ -1340,30 +1342,44 @@ creatura.register_utility("animalia:aerial_swarm", function(self, scale)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
creatura.register_utility("animalia:land", function(self, scale)
 | 
			
		||||
    scale = scale or 1
 | 
			
		||||
    local function func(self)
 | 
			
		||||
        if self.touching_ground then return true end
 | 
			
		||||
        local _, node = creatura.sensor_floor(self, 3, true)
 | 
			
		||||
        if node and is_liquid[node.name] then self.is_landed = false return true end
 | 
			
		||||
        scale = scale or 1
 | 
			
		||||
        local width = self.width
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        local pos2
 | 
			
		||||
        if self:timer(1) then
 | 
			
		||||
        if node and get_node_def(node.name).drawtype == "liquid" then self.is_landed = false return true end
 | 
			
		||||
        if not self:get_action() then
 | 
			
		||||
            local pos = self.object:get_pos()
 | 
			
		||||
            local offset = random(2 * scale, 3 * scale)
 | 
			
		||||
            if random(2) < 2 then
 | 
			
		||||
                offset = offset * -1
 | 
			
		||||
            end
 | 
			
		||||
            pos2 = {
 | 
			
		||||
            local pos2 = {
 | 
			
		||||
                x = pos.x + offset,
 | 
			
		||||
                y = pos.y,
 | 
			
		||||
                z = pos.z + offset
 | 
			
		||||
            }
 | 
			
		||||
            pos2.y = pos2.y - (3 * scale)
 | 
			
		||||
        end
 | 
			
		||||
        if not self:get_action()
 | 
			
		||||
        and pos2 then
 | 
			
		||||
            self:animate("fly")
 | 
			
		||||
            creatura.action_walk(self, pos2, 2, "animalia:fly_path", 1)
 | 
			
		||||
            animalia.action_boid_move(self, pos2, 2, "animalia:fly_path", 1)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    self:set_utility(func)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
creatura.register_utility("animalia:return_to_nest", function(self)
 | 
			
		||||
    local function func(self)
 | 
			
		||||
        if not self.home_position then return true end
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        local pos2 = self.home_position
 | 
			
		||||
        local dist = vec_dist(pos, {x = pos2.x, y = pos.y, z = pos2.z})
 | 
			
		||||
        if dist < 4
 | 
			
		||||
        and abs(pos.y - pos2.y) < 2 then
 | 
			
		||||
            if self.touching_ground then
 | 
			
		||||
                creatura.action_idle(self, 1)
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        if not self:get_action() then
 | 
			
		||||
            creatura.action_walk(self, pos2, 6, "animalia:fly_path", 1)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    self:set_utility(func)
 | 
			
		||||
@ -1522,9 +1538,6 @@ creatura.register_utility("animalia:return_to_home", function(self)
 | 
			
		||||
        if not self.home_position then return true end
 | 
			
		||||
        local pos = self.object:get_pos()
 | 
			
		||||
        local pos2 = self.home_position
 | 
			
		||||
        if not self:get_action() then
 | 
			
		||||
            creatura.action_walk(self, vec_raise(pos2, -1), 6, "animalia:fly_path", 1)
 | 
			
		||||
        end
 | 
			
		||||
        local dist = vec_dist(pos, pos2)
 | 
			
		||||
        if dist < 2 then
 | 
			
		||||
            if is_solid[minetest.get_node(vec_raise(pos, 1)).name] then
 | 
			
		||||
@ -1533,6 +1546,9 @@ creatura.register_utility("animalia:return_to_home", function(self)
 | 
			
		||||
                self.object:set_velocity({x = 0, y = 0, z = 0})
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
        if not self:get_action() then
 | 
			
		||||
            creatura.action_walk(self, vec_raise(pos2, -1), 6, "animalia:fly_path", 1)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    self:set_utility(func)
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
@ -76,7 +76,6 @@ creatura.register_mob_spawn("animalia:frog", {
 | 
			
		||||
    spawn_cluster = true,
 | 
			
		||||
    spawn_in_nodes = true,
 | 
			
		||||
    nodes = {"default:water_source"},
 | 
			
		||||
    send_debug = true
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:horse", {
 | 
			
		||||
@ -122,16 +121,33 @@ creatura.register_mob_spawn("animalia:wolf", {
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:bird", {
 | 
			
		||||
    chance = 4,
 | 
			
		||||
    chance = 1,
 | 
			
		||||
    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"}
 | 
			
		||||
    nodes = {"group:leaves"}
 | 
			
		||||
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
creatura.register_on_spawn("animalia:bird", function(self, pos)
 | 
			
		||||
    local node = minetest.get_node(pos)
 | 
			
		||||
    if node.name == "air" then
 | 
			
		||||
        minetest.set_node(pos, {name = "animalia:nest_song_bird"})
 | 
			
		||||
        self.home_position = self:memorize("home_position", pos)
 | 
			
		||||
        self.despawn_after = self:memorize("despawn_after", nil)
 | 
			
		||||
    else
 | 
			
		||||
        local nodes = minetest.find_nodes_in_area_under_air({x = pos.x - 3, y = pos.y - 3, z = pos.z - 3}, {x = pos.x + 3, y = pos.y + 7, z = pos.z + 3}, "group:leaves")
 | 
			
		||||
        if nodes[1] then
 | 
			
		||||
            pos = nodes[1]
 | 
			
		||||
            minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "animalia:nest_song_bird"})
 | 
			
		||||
            self.home_position = self:memorize("home_position", nodes[1])
 | 
			
		||||
            self.despawn_after = self:memorize("despawn_after", nil)
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
creatura.register_mob_spawn("animalia:tropical_fish", {
 | 
			
		||||
    chance = 3,
 | 
			
		||||
    min_height = -128,
 | 
			
		||||
@ -260,7 +276,8 @@ minetest.register_on_generated(function(minp, maxp)
 | 
			
		||||
                if spawnable_mobs
 | 
			
		||||
                and #spawnable_mobs > 0 then
 | 
			
		||||
                    local mob = spawnable_mobs[random(#spawnable_mobs)]
 | 
			
		||||
                    table.insert(animalia.spawn_queue, {pos = center, mob = mob, group = random(3, 4)})
 | 
			
		||||
                    local spawn_def = creatura.registered_mob_spawns[mob]
 | 
			
		||||
                    table.insert(animalia.spawn_queue, {pos = center, mob = mob, group = random(spawn_def.min_group, spawn_def.max_group)})
 | 
			
		||||
                    table.insert(animalia.spawn_points, center)
 | 
			
		||||
                end
 | 
			
		||||
                spawn_added = true
 | 
			
		||||
@ -297,7 +314,8 @@ minetest.register_globalstep(function(dtime)
 | 
			
		||||
                            end
 | 
			
		||||
                        end
 | 
			
		||||
                        if spawn then
 | 
			
		||||
                            table.insert(animalia.spawn_queue, {pos = point, mob = mob, group = random(3, 4)})
 | 
			
		||||
                            local spawn_def = creatura.registered_mob_spawns[mob]
 | 
			
		||||
                            table.insert(animalia.spawn_queue, {pos = point, mob = mob, group = random(spawn_def.min_group, spawn_def.max_group)})
 | 
			
		||||
                        end
 | 
			
		||||
                    end
 | 
			
		||||
                end
 | 
			
		||||
@ -316,16 +334,25 @@ local function spawn_queued()
 | 
			
		||||
		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)
 | 
			
		||||
                    }
 | 
			
		||||
                if queue[i].group > 4
 | 
			
		||||
                or creatura.registered_mob_spawns[queue[i].mob].spawn_cluster then
 | 
			
		||||
                    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)
 | 
			
		||||
                    meta:set_string("cluster", queue[i].group)
 | 
			
		||||
                else
 | 
			
		||||
                    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
 | 
			
		||||
            end
 | 
			
		||||
			table.remove(animalia.spawn_queue, i)
 | 
			
		||||
 | 
			
		||||
@ -355,6 +355,26 @@ minetest.register_craftitem("animalia:bucket_guano", {
 | 
			
		||||
    end
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_node("animalia:nest_song_bird", {
 | 
			
		||||
	description = "Song Bird Nest",
 | 
			
		||||
	paramtype = "light",
 | 
			
		||||
	drawtype = "mesh",
 | 
			
		||||
	mesh = "animalia_nest.obj",
 | 
			
		||||
	tiles = {"animalia_nest.png"},
 | 
			
		||||
	sunlight_propagates = true,
 | 
			
		||||
	stack_max = 1,
 | 
			
		||||
	groups = {snappy = 3, flammable = 3},
 | 
			
		||||
	selection_box = {
 | 
			
		||||
        type = "fixed",
 | 
			
		||||
        fixed = {-5 / 16, -0.5, -5 / 16, 5 / 16, -0.31, 5 / 16},
 | 
			
		||||
    },
 | 
			
		||||
	node_box = {
 | 
			
		||||
        type = "fixed",
 | 
			
		||||
        fixed = {-5 / 16, -0.5, -5 / 16, 5 / 16, -0.31, 5 / 16},
 | 
			
		||||
    },
 | 
			
		||||
	drops = "default:stick"
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
-----------
 | 
			
		||||
-- Tools --
 | 
			
		||||
-----------
 | 
			
		||||
@ -365,6 +385,56 @@ minetest.register_craftitem("animalia:cat_toy", {
 | 
			
		||||
    wield_image = "animalia_cat_toy.png^[transformFYR90",
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
local nametag = {}
 | 
			
		||||
 | 
			
		||||
local function get_rename_formspec(meta)
 | 
			
		||||
    local tag = meta:get_string("name") or ""
 | 
			
		||||
    local form = {
 | 
			
		||||
        "size[8,4]",
 | 
			
		||||
        "field[0.5,1;7.5,0;name;" .. minetest.formspec_escape("Enter name:") .. ";" .. tag .. "]",
 | 
			
		||||
        "button_exit[2.5,3.5;3,1;set_name;" .. minetest.formspec_escape("Set Name") .. "]"
 | 
			
		||||
    }
 | 
			
		||||
    return table.concat(form, "")
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
			
		||||
    if formname == "animalia:set_name" and fields.name then
 | 
			
		||||
        local name = player:get_player_name()
 | 
			
		||||
        if not nametag[name] then
 | 
			
		||||
            return
 | 
			
		||||
        end
 | 
			
		||||
        local itemstack = nametag[name]
 | 
			
		||||
        if string.len(fields.name) > 64 then
 | 
			
		||||
            fields.name = string.sub(fields.name, 1, 64)
 | 
			
		||||
        end
 | 
			
		||||
		local meta = itemstack:get_meta()
 | 
			
		||||
		meta:set_string("name", fields.name)
 | 
			
		||||
		meta:set_string("description", fields.name)
 | 
			
		||||
		player:set_wielded_item(itemstack)
 | 
			
		||||
        if fields.quit or fields.key_enter then
 | 
			
		||||
            nametag[name] = nil
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local function nametag_rightclick(itemstack, player, pointed_thing)
 | 
			
		||||
	if pointed_thing
 | 
			
		||||
	and pointed_thing.type == "object" then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local name = player:get_player_name()
 | 
			
		||||
	nametag[name] = itemstack
 | 
			
		||||
	local meta = itemstack:get_meta()
 | 
			
		||||
	minetest.show_formspec(name, "animalia:set_name", get_rename_formspec(meta))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:nametag", {
 | 
			
		||||
    description = "Nametag",
 | 
			
		||||
    inventory_image = "animalia_nametag.png",
 | 
			
		||||
	on_rightclick = nametag_rightclick,
 | 
			
		||||
	on_secondary_use = nametag_rightclick
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
minetest.register_craftitem("animalia:saddle", {
 | 
			
		||||
    description = "Saddle",
 | 
			
		||||
    inventory_image = "animalia_saddle.png",
 | 
			
		||||
@ -493,7 +563,7 @@ function animalia.show_libri_main_form(player, pages, group)
 | 
			
		||||
    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]"
 | 
			
		||||
        "background[-0.7,-0.5;17.5,11.5;animalia_libri_bg.png]"
 | 
			
		||||
	}, "")
 | 
			
		||||
	if group == 1 then
 | 
			
		||||
		if pages[1] then
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						@ -13,8 +13,19 @@ minetest.register_on_leaveplayer(function(player)
 | 
			
		||||
    animalia.pets[name] = nil
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
local path = minetest.get_modpath("animalia")
 | 
			
		||||
-- Daytime Tracking
 | 
			
		||||
 | 
			
		||||
animalia.is_day = true
 | 
			
		||||
 | 
			
		||||
local function is_day()
 | 
			
		||||
    local time = (minetest.get_timeofday() or 0) * 24000
 | 
			
		||||
    animalia.is_day = time < 19500 and time > 4500
 | 
			
		||||
    minetest.after(10, is_day)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
is_day()
 | 
			
		||||
 | 
			
		||||
local path = minetest.get_modpath("animalia")
 | 
			
		||||
 | 
			
		||||
dofile(path.."/api/api.lua")
 | 
			
		||||
dofile(path.."/api/behaviors.lua")
 | 
			
		||||
 | 
			
		||||
@ -182,7 +182,6 @@ creatura.register_mob("animalia:bat", {
 | 
			
		||||
    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
 | 
			
		||||
@ -261,16 +260,15 @@ creatura.register_mob("animalia:bat", {
 | 
			
		||||
    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
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			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
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -36,7 +36,7 @@ creatura.register_mob("animalia:bird", {
 | 
			
		||||
	stepheight = 1.1,
 | 
			
		||||
	max_fall = 100,
 | 
			
		||||
	turn_rate = 6,
 | 
			
		||||
	boid_seperation = 1,
 | 
			
		||||
	boid_seperation = 0.4,
 | 
			
		||||
    -- Visuals
 | 
			
		||||
    mesh = "animalia_bird.b3d",
 | 
			
		||||
    hitbox = {
 | 
			
		||||
@ -53,7 +53,7 @@ creatura.register_mob("animalia:bird", {
 | 
			
		||||
		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,
 | 
			
		||||
	catch_with_lasso = false,
 | 
			
		||||
@ -96,14 +96,14 @@ creatura.register_mob("animalia:bird", {
 | 
			
		||||
					if self.in_liquid then
 | 
			
		||||
						self.stamina = self:memorize("stamina", 30)
 | 
			
		||||
						self.is_landed = false
 | 
			
		||||
						return 0.15, {self, 1}
 | 
			
		||||
						return 0.15, {self, 0.5}
 | 
			
		||||
					end
 | 
			
		||||
					local player = creatura.get_nearby_player(self)
 | 
			
		||||
					if player
 | 
			
		||||
					and player:get_pos() then
 | 
			
		||||
						local dist = vector.distance(pos, player:get_pos())
 | 
			
		||||
						self.is_landed = false
 | 
			
		||||
						return (16 - dist) * 0.1, {self, 1}
 | 
			
		||||
						return (16 - dist) * 0.1, {self, 0.5}
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
@ -112,28 +112,72 @@ creatura.register_mob("animalia:bird", {
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:land",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.is_landed
 | 
			
		||||
				if self.is_landed
 | 
			
		||||
				and not self.touching_ground
 | 
			
		||||
				and not self.in_liquid then
 | 
			
		||||
					return 0.12, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			utility = "animalia:return_to_nest",
 | 
			
		||||
			get_score = function(self)
 | 
			
		||||
				if not self.home_position then
 | 
			
		||||
					local pos = self.object:get_pos()
 | 
			
		||||
					local node = minetest.get_node({x = pos.x, y = pos.y - 1, z = pos.z})
 | 
			
		||||
					if minetest.get_item_group(node, "leaves") > 0 then
 | 
			
		||||
						self.home_position = self:memorize({
 | 
			
		||||
							x = math.floor(pos.x + 0.5),
 | 
			
		||||
							y = math.floor(pos.y + 0.5),
 | 
			
		||||
							z = math.floor(pos.z + 0.5)
 | 
			
		||||
						})
 | 
			
		||||
						minetest.set_node(self.home_position, {name = "animalia:nest_song_bird"})
 | 
			
		||||
					end
 | 
			
		||||
					return 0
 | 
			
		||||
				end
 | 
			
		||||
				local player = self._nearby_player
 | 
			
		||||
				if player
 | 
			
		||||
				and player:get_pos() then
 | 
			
		||||
					local pos = self.object:get_pos()
 | 
			
		||||
					local dist = vector.distance(pos, player:get_pos())
 | 
			
		||||
					if dist < 3 then
 | 
			
		||||
						return 0
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
				if not animalia.is_day then
 | 
			
		||||
					return 0.6, {self}
 | 
			
		||||
				end
 | 
			
		||||
				return 0
 | 
			
		||||
			end
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
		self.trust = self:recall("trust") or {}
 | 
			
		||||
		self._tp2home = self:recall("_tp2home") or nil
 | 
			
		||||
		self.home_position = self:recall("home_position") or nil
 | 
			
		||||
		if self._tp2home
 | 
			
		||||
		and self.home_position then
 | 
			
		||||
			self.object:set_pos(self.home_position)
 | 
			
		||||
		end
 | 
			
		||||
		self.is_landed = self:recall("is_landed") or false
 | 
			
		||||
		self.stamina = self:recall("stamina") or 0.1
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		self.stamina = self:recall("stamina") or 40
 | 
			
		||||
		if not self.home_position then
 | 
			
		||||
			local pos = self.object:get_pos()
 | 
			
		||||
			local nests = minetest.find_nodes_in_area_under_air(vector.add(pos, 4), vector.subtract(pos, 4), {"animalia:nest_song_bird"})
 | 
			
		||||
			if nests[1]
 | 
			
		||||
			and minetest.get_natural_light(nests[1]) > 0 then
 | 
			
		||||
				self.home_position = self:memorize("home_position", nests[1])
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
    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 animalia.is_day
 | 
			
		||||
		and self:timer(random(10,15)) then
 | 
			
		||||
			if self.texture_no == 1 then
 | 
			
		||||
				self:play_sound("cardinal")
 | 
			
		||||
			elseif self.texture_no == 2 then
 | 
			
		||||
@ -177,18 +221,29 @@ creatura.register_mob("animalia:bird", {
 | 
			
		||||
			self:initiate_utility("animalia:die", self)
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	deactivate_func = function(self)
 | 
			
		||||
		if self:get_utility()
 | 
			
		||||
		and self:get_utility() == "animalia:return_to_nest" then
 | 
			
		||||
			local pos = self.home_position
 | 
			
		||||
			local node = minetest.get_node_or_nil(pos)
 | 
			
		||||
			if node
 | 
			
		||||
			and node.name == "animalia:nest_song_bird"
 | 
			
		||||
			and minetest.get_natural_light(pos) > 0 then
 | 
			
		||||
				self:memorize("_tp2home", true)
 | 
			
		||||
			end
 | 
			
		||||
		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
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			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
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -226,6 +226,9 @@ creatura.register_mob("animalia:cat", {
 | 
			
		||||
			end
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		-- Initiate trust
 | 
			
		||||
		if not self.trust[clicker:get_player_name()] then
 | 
			
		||||
			self.trust[clicker:get_player_name()] = 0
 | 
			
		||||
 | 
			
		||||
@ -135,8 +135,6 @@ creatura.register_mob("animalia:chicken", {
 | 
			
		||||
    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)
 | 
			
		||||
@ -153,6 +151,9 @@ creatura.register_mob("animalia:chicken", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) 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)
 | 
			
		||||
 | 
			
		||||
@ -153,8 +153,6 @@ creatura.register_mob("animalia:cow", {
 | 
			
		||||
		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)
 | 
			
		||||
@ -171,6 +169,9 @@ creatura.register_mob("animalia:cow", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		local name = clicker:get_player_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -187,6 +187,9 @@ creatura.register_mob("animalia:frog", {
 | 
			
		||||
			self:memorize("trust", self.trust)
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			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)
 | 
			
		||||
 | 
			
		||||
@ -189,7 +189,6 @@ creatura.register_mob("animalia:horse", {
 | 
			
		||||
    activate_func = function(self)
 | 
			
		||||
		animalia.initialize_api(self)
 | 
			
		||||
		animalia.initialize_lasso(self)
 | 
			
		||||
        self._path = {}
 | 
			
		||||
		set_pattern(self)
 | 
			
		||||
		self.owner = self:recall("owner") or nil
 | 
			
		||||
		if self.owner then
 | 
			
		||||
@ -267,6 +266,9 @@ creatura.register_mob("animalia:horse", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		local tool_name = clicker:get_wielded_item():get_name()
 | 
			
		||||
		if self.owner
 | 
			
		||||
 | 
			
		||||
@ -144,8 +144,6 @@ creatura.register_mob("animalia:pig", {
 | 
			
		||||
    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)
 | 
			
		||||
@ -161,6 +159,9 @@ creatura.register_mob("animalia:pig", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "pig", form = "pg_pig;Pigs"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
 | 
			
		||||
@ -121,8 +121,6 @@ creatura.register_mob("animalia:reindeer", {
 | 
			
		||||
    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)
 | 
			
		||||
@ -139,6 +137,9 @@ creatura.register_mob("animalia:reindeer", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		animalia.add_libri_page(self, clicker, {name = "reindeer", form = "pg_reindeer;Reindeer"})
 | 
			
		||||
	end,
 | 
			
		||||
	on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
 | 
			
		||||
 | 
			
		||||
@ -196,6 +196,9 @@ creatura.register_mob("animalia:sheep", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		local tool = clicker:get_wielded_item()
 | 
			
		||||
		local tool_name = tool:get_name()
 | 
			
		||||
		if tool_name == "animalia:shears"
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,6 @@ creatura.register_mob("animalia:tropical_fish", {
 | 
			
		||||
    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",
 | 
			
		||||
@ -76,6 +75,9 @@ creatura.register_mob("animalia:tropical_fish", {
 | 
			
		||||
		end
 | 
			
		||||
    end,
 | 
			
		||||
	on_rightclick = function(self, clicker)
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		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)
 | 
			
		||||
 | 
			
		||||
@ -126,8 +126,6 @@ creatura.register_mob("animalia:turkey", {
 | 
			
		||||
    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)
 | 
			
		||||
@ -144,6 +142,9 @@ creatura.register_mob("animalia:turkey", {
 | 
			
		||||
		if animalia.feed(self, clicker, false, true) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) 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)
 | 
			
		||||
 | 
			
		||||
@ -201,6 +201,9 @@ creatura.register_mob("animalia:wolf", {
 | 
			
		||||
		if animalia.feed(self, clicker, passive, passive) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if animalia.set_nametag(self, clicker) then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
		if self.owner
 | 
			
		||||
		and clicker:get_player_name() == self.owner
 | 
			
		||||
		and clicker:get_player_control().sneak then
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										3
									
								
								mod.conf
									
									
									
									
									
								
							
							
						
						@ -2,3 +2,6 @@ name = animalia
 | 
			
		||||
depends = creatura
 | 
			
		||||
optional_depends = default, mcl_player
 | 
			
		||||
description = Adds unique and consistantly designed Animals
 | 
			
		||||
release = 11481
 | 
			
		||||
author = ElCeejo
 | 
			
		||||
title = Animalia
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								models/animalia_nest.mtl
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,4 @@
 | 
			
		||||
# Made in Blockbench 4.1.5
 | 
			
		||||
newmtl m_1
 | 
			
		||||
map_Kd animalia_nest.png 
 | 
			
		||||
newmtl none
 | 
			
		||||
							
								
								
									
										49
									
								
								models/animalia_nest.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,49 @@
 | 
			
		||||
# Made in Blockbench 4.1.5
 | 
			
		||||
mtllib animalia_nest.mtl
 | 
			
		||||
 | 
			
		||||
o cube
 | 
			
		||||
v 0.3125 -0.3125 0.3125
 | 
			
		||||
v 0.3125 -0.3125 -0.3125
 | 
			
		||||
v 0.3125 -0.5 0.3125
 | 
			
		||||
v 0.3125 -0.5 -0.3125
 | 
			
		||||
v -0.3125 -0.3125 -0.3125
 | 
			
		||||
v -0.3125 -0.3125 0.3125
 | 
			
		||||
v -0.3125 -0.5 -0.3125
 | 
			
		||||
v -0.3125 -0.5 0.3125
 | 
			
		||||
vt 0.16666666666666666 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.45833333333333337
 | 
			
		||||
vt 0.16666666666666666 0.45833333333333337
 | 
			
		||||
vt 1 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 1
 | 
			
		||||
vt 1 1
 | 
			
		||||
vt 1 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.5833333333333333
 | 
			
		||||
vt 0.5833333333333334 0.16666666666666663
 | 
			
		||||
vt 1 0.16666666666666663
 | 
			
		||||
vn 0 0 -1
 | 
			
		||||
vn 1 0 0
 | 
			
		||||
vn 0 0 1
 | 
			
		||||
vn -1 0 0
 | 
			
		||||
vn 0 1 0
 | 
			
		||||
vn 0 -1 0
 | 
			
		||||
usemtl m_1
 | 
			
		||||
f 4/4/1 7/3/1 5/2/1 2/1/1
 | 
			
		||||
f 3/8/2 4/7/2 2/6/2 1/5/2
 | 
			
		||||
f 8/12/3 3/11/3 1/10/3 6/9/3
 | 
			
		||||
f 7/16/4 8/15/4 6/14/4 5/13/4
 | 
			
		||||
f 6/20/5 1/19/5 2/18/5 5/17/5
 | 
			
		||||
f 7/24/6 4/23/6 3/22/6 8/21/6
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								models/animalia_nest.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.4 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/animalia_nest.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 7.4 KiB  | 
| 
		 Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 19 KiB  | 
| 
		 Before Width: | Height: | Size: 19 KiB  | 
| 
		 Before Width: | Height: | Size: 60 KiB  | 
| 
		 Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.6 KiB  | 
| 
		 Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.6 KiB  | 
| 
		 Before Width: | Height: | Size: 5.3 KiB After Width: | Height: | Size: 5.5 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								textures/items/animalia_nametag.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 5.6 KiB  |