QoL Update

This commit is contained in:
ElCeejo 2023-03-15 14:27:40 -07:00
parent 1b9382bee3
commit 5cd21a7a37
62 changed files with 2078 additions and 1614 deletions

View file

@ -2,18 +2,6 @@
-- API -- -- API --
--------- ---------
animalia.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(animalia.walkable_nodes, name)
end
end
end
end)
-- Math -- -- Math --
local abs = math.abs local abs = math.abs
@ -65,12 +53,6 @@ local vec_len = vector.length
local dir2yaw = minetest.dir_to_yaw local dir2yaw = minetest.dir_to_yaw
local yaw2dir = minetest.yaw_to_dir local yaw2dir = minetest.yaw_to_dir
--------------
-- Settings --
--------------
local creative = minetest.settings:get_bool("creative_mode")
------------ ------------
-- Common -- -- Common --
------------ ------------
@ -88,8 +70,6 @@ function animalia.correct_name(str)
end end
end end
local correct_name = animalia.correct_name
--------------------- ---------------------
-- Local Utilities -- -- Local Utilities --
--------------------- ---------------------
@ -109,7 +89,7 @@ if minetest.get_modpath("default")
and minetest.get_modpath("player_api") then and minetest.get_modpath("player_api") then
animate_player = player_api.set_animation animate_player = player_api.set_animation
elseif minetest.get_modpath("mcl_player") then elseif minetest.get_modpath("mcl_player") then
animate_player = mcl_player.set_animation animate_player = mcl_player.player_set_animation
end end
----------------------- -----------------------
@ -269,16 +249,8 @@ end
function animalia.particle_spawner(pos, texture, type, min_pos, max_pos) function animalia.particle_spawner(pos, texture, type, min_pos, max_pos)
type = type or "float" type = type or "float"
min_pos = min_pos or { min_pos = min_pos or vec_sub(pos, 2)
x = pos.x - 2, max_pos = max_pos or vec_add(pos, 2)
y = pos.y - 2,
z = pos.z - 2,
}
max_pos = max_pos or {
x = pos.x + 2,
y = pos.y + 2,
z = pos.z + 2,
}
if type == "float" then if type == "float" then
minetest.add_particlespawner({ minetest.add_particlespawner({
amount = 16, amount = 16,
@ -312,14 +284,52 @@ function animalia.particle_spawner(pos, texture, type, min_pos, max_pos)
end end
end end
function animalia.add_food_particle(self, item_name)
local pos, yaw = self.object:get_pos(), self.object:get_yaw()
if not pos then return end
local head = self.head_data
local offset_h = (head and head.pivot_h) or self.width
local offset_v = (head and head.pivot_v) or self.height
local head_pos = {
x = pos.x + sin(yaw) * -offset_h,
y = pos.y + offset_v,
z = pos.z + cos(yaw) * offset_h
}
local def = minetest.registered_items[item_name]
local image = def.inventory_image
if def.tiles then
image = def.tiles[1].name or def.tiles[1]
end
if image then
local crop = "^[sheet:4x4:" .. random(4) .. "," .. random(4)
minetest.add_particlespawner({
pos = head_pos,
time = 0.5,
amount = 12,
collisiondetection = true,
collision_removal = true,
vel = {min = {x = -1, y = 1, z = -1}, max = {x = 1, y = 2, z = 1}},
acc = {x = 0, y = -9.8, z = 0},
size = {min = 1, max = 2},
texture = image .. crop
})
end
end
---------- ----------
-- Mobs -- -- Mobs --
---------- ----------
function animalia.get_dropped_food(self, item) function animalia.death_func(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end
function animalia.get_dropped_food(self, item, radius)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return end if not pos then return end
local objects = minetest.get_objects_inside_radius(pos, self.tracking_range) local objects = minetest.get_objects_inside_radius(pos, radius or self.tracking_range)
for _, object in ipairs(objects) do for _, object in ipairs(objects) do
local ent = object:get_luaentity() local ent = object:get_luaentity()
if ent if ent
@ -337,6 +347,19 @@ function animalia.protect_from_despawn(self)
self.despawn_after = self:memorize("despawn_after", false) self.despawn_after = self:memorize("despawn_after", false)
end end
function animalia.despawn_inactive_mob(self)
local os_time = os.time()
self._last_active = self:recall("_last_active")
if self._last_active
and self.despawn_after then
local last_active = self._last_active
if os_time - last_active > self.despawn_after then
self.object:remove()
return true
end
end
end
function animalia.set_nametag(self, clicker) function animalia.set_nametag(self, clicker)
local plyr_name = clicker and clicker:get_player_name() local plyr_name = clicker and clicker:get_player_name()
if not plyr_name then return end if not plyr_name then return end
@ -391,7 +414,12 @@ function animalia.initialize_api(self)
self.texture_no = random(#textures) self.texture_no = random(#textures)
end end
self:set_texture(self.texture_no, textures) self:set_texture(self.texture_no, textures)
return end
if self.growth_scale < 0.8
and self.child_mesh then
self.object:set_properties({
mesh = self.child_mesh
})
end end
end end
@ -406,6 +434,7 @@ function animalia.step_timers(self)
end end
self:memorize("breeding_cooldown", self.breeding_cooldown) self:memorize("breeding_cooldown", self.breeding_cooldown)
self:memorize("trust_cooldown", self.trust_cooldown) self:memorize("trust_cooldown", self.trust_cooldown)
self:memorize("_last_active", os.time())
end end
function animalia.do_growth(self, interval) function animalia.do_growth(self, interval)
@ -422,6 +451,7 @@ function animalia.do_growth(self, interval)
end end
self:set_texture(tex_no, self.child_textures) self:set_texture(tex_no, self.child_textures)
elseif self.growth_scale == 0.8 then elseif self.growth_scale == 0.8 then
if self.child_mesh then self:set_mesh() end
if self.male_textures if self.male_textures
and self.female_textures then and self.female_textures then
if #self.child_textures == 1 then if #self.child_textures == 1 then
@ -434,6 +464,9 @@ function animalia.do_growth(self, interval)
end end
self:set_texture(self.texture_no, self.textures) self:set_texture(self.texture_no, self.textures)
end end
if self.on_grown then
self:on_grown()
end
end end
self:memorize("growth_scale", self.growth_scale) self:memorize("growth_scale", self.growth_scale)
end end
@ -448,6 +481,7 @@ function animalia.random_sound(self)
end end
function animalia.add_trust(self, player, amount) function animalia.add_trust(self, player, amount)
if self.trust_cooldown > 0 then return end
self.trust_cooldown = 60 self.trust_cooldown = 60
local plyr_name = player:get_player_name() local plyr_name = player:get_player_name()
local trust = self.trust[plyr_name] or 0 local trust = self.trust[plyr_name] or 0
@ -513,7 +547,7 @@ function animalia.feed(self, clicker, tame, breed)
if self.breeding_cooldown <= 0 then if self.breeding_cooldown <= 0 then
self.breeding = true self.breeding = true
self.breeding_cooldown = 60 self.breeding_cooldown = 60
animalia.particle_spawner(pos, "heart.png", "float", minp, maxp) animalia.particle_spawner(pos, "heart.png", "float")
end end
end end
self._despawn = self:memorize("_despawn", false) self._despawn = self:memorize("_despawn", false)
@ -575,6 +609,26 @@ function animalia.punch(self, puncher, ...)
end end
end end
function animalia.find_crop(self)
local pos = self.object:get_pos()
if not pos then return end
local nodes = minetest.find_nodes_in_area(vec_sub(pos, 6), vec_add(pos, 6), "group:crop") or {}
if #nodes < 1 then return end
return nodes[math.random(#nodes)]
end
function animalia.eat_crop(self, pos)
local node_name = minetest.get_node(pos).name
local new_name = node_name:sub(1, #node_name - 1) .. (tonumber(node_name:sub(-1)) or 2) - 1
local new_def = minetest.registered_nodes[new_name]
if not new_def then return false end
local p2 = new_def.place_param2 or 1
minetest.set_node(pos, {name = new_name, param2 = p2})
animalia.add_food_particle(self, new_name)
return true
end
-------------- --------------
-- Spawning -- -- Spawning --
-------------- --------------

File diff suppressed because it is too large Load diff

View file

@ -3,18 +3,9 @@
----------- -----------
local abs = math.abs local abs = math.abs
local asin = math.asin
local atan2 = math.atan2
local cos = math.cos
local deg = math.deg
local sin = math.sin
local function diff(a, b) -- Get difference between 2 angles
return atan2(sin(b - a), cos(b - a))
end
local vec_add, vec_dir, vec_dist, vec_len = vector.add, vector.direction, vector.distance, vector.length local vec_add, vec_dir, vec_dist, vec_len = vector.add, vector.direction, vector.distance, vector.length
local dir2yaw, dir2rot = minetest.dir_to_yaw, vector.dir_to_rotation local dir2rot = vector.dir_to_rotation
-- Entities -- -- Entities --
@ -29,7 +20,7 @@ minetest.register_entity("animalia:lasso_entity", {
self.object:set_armor_groups({immortal = 1}) self.object:set_armor_groups({immortal = 1})
end, end,
_scale = 1, _scale = 1,
on_step = function(self, dtime) on_step = function(self)
local pos, parent = self.object:get_pos(), (self.object:get_attach() or self._attached) local pos, parent = self.object:get_pos(), (self.object:get_attach() or self._attached)
local pointed_ent = self._point_to and self._point_to:get_luaentity() local pointed_ent = self._point_to and self._point_to:get_luaentity()
local point_to = self._point_to and self._point_to:get_pos() local point_to = self._point_to and self._point_to:get_pos()
@ -126,10 +117,10 @@ local function add_lasso(self, origin)
if not ent then return end if not ent then return end
-- Attachment point of entity -- Attachment point of entity
ent._attached = origin ent._attached = origin
if type(origin) == "string" then if type(origin) ~= "string" then
--local player = minetest.get_player_by_name(origin) --local player = minetest.get_player_by_name(origin)
--object:set_attach(player) --object:set_attach(player)
else --else
object:set_pos(origin) object:set_pos(origin)
end end
self._lassod_to = origin self._lassod_to = origin

View file

@ -8,8 +8,6 @@ local path = minetest.get_modpath(minetest.get_current_modname())
local color = minetest.colorize local color = minetest.colorize
local page_spacing = 0.5
local libri_bg = { local libri_bg = {
"formspec_version[3]", "formspec_version[3]",
"size[16,10]", "size[16,10]",
@ -33,7 +31,6 @@ local pages = {}
local generate_mobs = { local generate_mobs = {
["animalia:bat"] = "Bat", ["animalia:bat"] = "Bat",
["animalia:bird"] = "Song Bird",
["animalia:cat"] = "Cat", ["animalia:cat"] = "Cat",
["animalia:chicken"] = "Chicken", ["animalia:chicken"] = "Chicken",
["animalia:cow"] = "Cow", ["animalia:cow"] = "Cow",
@ -46,6 +43,7 @@ local generate_mobs = {
["animalia:rat"] = "Rat", ["animalia:rat"] = "Rat",
["animalia:reindeer"] = "Reindeer", ["animalia:reindeer"] = "Reindeer",
["animalia:sheep"] = "Sheep", ["animalia:sheep"] = "Sheep",
["animalia:song_bird"] = "Song Bird",
["animalia:turkey"] = "Turkey", ["animalia:turkey"] = "Turkey",
["animalia:wolf"] = "Wolf", ["animalia:wolf"] = "Wolf",
} }
@ -53,7 +51,6 @@ local generate_mobs = {
local spawn_biomes = { local spawn_biomes = {
["animalia:bat"] = "cave", ["animalia:bat"] = "cave",
["animalia:bird"] = "temperate",
["animalia:cat"] = "urban", ["animalia:cat"] = "urban",
["animalia:chicken"] = "tropical", ["animalia:chicken"] = "tropical",
["animalia:cow"] = "grassland", ["animalia:cow"] = "grassland",
@ -66,6 +63,7 @@ local spawn_biomes = {
["animalia:rat"] = "urban", ["animalia:rat"] = "urban",
["animalia:reindeer"] = "boreal", ["animalia:reindeer"] = "boreal",
["animalia:sheep"] = "grassland", ["animalia:sheep"] = "grassland",
["animalia:song_bird"] = "temperate",
["animalia:turkey"] = "boreal", ["animalia:turkey"] = "boreal",
["animalia:wolf"] = "boreal", ["animalia:wolf"] = "boreal",
} }
@ -310,13 +308,14 @@ function libri.render_element(def, meta, playername)
local filename = path .. "/libri/" .. def.file local filename = path .. "/libri/" .. def.file
local file = io.open(filename) local file = io.open(filename)
if file then if file then
local i = 0 local text = ""
local full_text = ""
for line in file:lines() do for line in file:lines() do
full_text = full_text .. line .. "\n" text = text .. line .. "\n"
end end
local total_offset = (offset_x + (0.35 - 0.35 * font_size_x)) .. "," .. offset_y local total_offset = (offset_x + (0.35 - 0.35 * font_size_x)) .. "," .. offset_y
form = form .. "hypertext[" .. total_offset .. ";8,9;text;<global color=#000000 size=".. font_size .. " halign=center>" .. full_text .. "]" form = form ..
"hypertext[" .. total_offset .. ";8,9;text;<global color=#000000 size="..
font_size .. " halign=center>" .. text .. "]"
file:close() file:close()
end end
else else

View file

@ -2,11 +2,20 @@
-- Spawning -- -- Spawning --
-------------- --------------
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 common_spawn_chance = tonumber(minetest.settings:get("animalia_common_chance")) or 20000 local common_spawn_chance = tonumber(minetest.settings:get("animalia_common_chance")) or 20000
local ambient_spawn_chance = tonumber(minetest.settings:get("animalia_ambient_chance")) or 6000 local ambient_spawn_chance = tonumber(minetest.settings:get("animalia_ambient_chance")) or 6000
local pest_spawn_chance = tonumber(minetest.settings:get("animalia_pest_chance")) or 4000 local pest_spawn_chance = tonumber(minetest.settings:get("animalia_pest_chance")) or 2000
local predator_spawn_chance = tonumber(minetest.settings:get("animalia_predator_chance")) or 30000 local predator_spawn_chance = tonumber(minetest.settings:get("animalia_predator_chance")) or 30000
@ -43,6 +52,17 @@ creatura.register_abm_spawn("animalia:chicken", {
nodes = {"group:soil"}, nodes = {"group:soil"},
}) })
creatura.register_abm_spawn("animalia:cat", {
chance = common_spawn_chance,
min_height = 0,
max_height = 1024,
min_group = 1,
max_group = 2,
nodes = {"group:soil"},
neighbors = {"group:wood"}
})
creatura.register_abm_spawn("animalia:cow", { creatura.register_abm_spawn("animalia:cow", {
chance = common_spawn_chance, chance = common_spawn_chance,
min_height = 0, min_height = 0,
@ -76,7 +96,7 @@ creatura.register_abm_spawn("animalia:horse", {
}) })
creatura.register_abm_spawn("animalia:rat", { creatura.register_abm_spawn("animalia:rat", {
chance = 2000, chance = pest_spawn_chance,
interval = 60, interval = 60,
min_height = -1, min_height = -1,
max_height = 1024, max_height = 1024,
@ -162,7 +182,7 @@ creatura.register_abm_spawn("animalia:bat", {
nodes = {"group:stone"} nodes = {"group:stone"}
}) })
creatura.register_abm_spawn("animalia:bird", { creatura.register_abm_spawn("animalia:song_bird", {
chance = ambient_spawn_chance, chance = ambient_spawn_chance,
interval = 60, interval = 60,
min_light = 0, min_light = 0,
@ -170,25 +190,21 @@ creatura.register_abm_spawn("animalia:bird", {
max_height = 1024, max_height = 1024,
min_group = 6, min_group = 6,
max_group = 12, max_group = 12,
spawn_cap = 12, spawn_cap = 6,
nodes = {"group:leaves"}, nodes = {"group:leaves", "animalia:nest_song_bird"},
neighbors = {"group:leaves"} neighbors = {"group:leaves"}
}) })
creatura.register_on_spawn("animalia:bird", function(self, pos) creatura.register_on_spawn("animalia:song_bird", function(self, pos)
local nests = minetest.find_nodes_in_area_under_air( local nests = minetest.find_nodes_in_area_under_air(
{x = pos.x - 12, y = pos.y - 12, z = pos.z - 12}, {x = pos.x - 16, y = pos.y - 16, z = pos.z - 16},
{x = pos.x + 12, y = pos.y + 12, z = pos.z + 12}, {x = pos.x + 16, y = pos.y + 16, z = pos.z + 16},
"animalia:nest_song_bird" "animalia:nest_song_bird"
) )
if nests[1] then if nests[1] then return end
self.home_position = self:memorize("home_position", nests[1])
return
end
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node.name == "air" then if node.name == "air" then
minetest.set_node(pos, {name = "animalia:nest_song_bird"}) minetest.set_node(pos, {name = "animalia:nest_song_bird"})
self.home_position = self:memorize("home_position", pos)
else else
local nodes = minetest.find_nodes_in_area_under_air( 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 - 3, z = pos.z - 3},
@ -198,23 +214,42 @@ creatura.register_on_spawn("animalia:bird", function(self, pos)
if nodes[1] then if nodes[1] then
pos = nodes[1] pos = nodes[1]
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "animalia:nest_song_bird"}) 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", {x = pos.x, y = pos.y + 1, z = pos.z})
end end
end end
end) end)
creatura.register_abm_spawn("animalia:frog", { creatura.register_abm_spawn("animalia:frog", {
chance = ambient_spawn_chance, chance = ambient_spawn_chance * 0.75,
interval = 60, interval = 60,
min_light = 0, min_light = 0,
min_height = -1, min_height = -1,
max_height = 8, max_height = 8,
min_group = 2, min_group = 1,
max_group = 4, max_group = 2,
neighbors = {"group:water"}, neighbors = {"group:water"},
nodes = {"group:soil"} nodes = {"group:soil"}
}) })
creatura.register_on_spawn("animalia:frog", function(self, pos)
local biome_data = minetest.get_biome_data(pos)
local biome_name = minetest.get_biome_name(biome_data.biome)
if is_value_in_table(animalia.registered_biome_groups["tropical"].biomes, biome_name) then
self:set_mesh(3)
elseif is_value_in_table(animalia.registered_biome_groups["temperate"].biomes, biome_name)
or is_value_in_table(animalia.registered_biome_groups["boreal"].biomes, biome_name) then
self:set_mesh(1)
elseif is_value_in_table(animalia.registered_biome_groups["grassland"].biomes, biome_name) then
self:set_mesh(2)
else
self.object:remove()
end
local activate = self.activate_func
activate(self)
end)
creatura.register_abm_spawn("animalia:tropical_fish", { creatura.register_abm_spawn("animalia:tropical_fish", {
chance = ambient_spawn_chance, chance = ambient_spawn_chance,
min_height = -128, min_height = -128,

View file

@ -54,6 +54,7 @@ local function register_egg(name, def)
if random(3) < 2 then if random(3) < 2 then
local object = minetest.add_entity(pos, def.mob) local object = minetest.add_entity(pos, def.mob)
local ent = object and object:get_luaentity() local ent = object and object:get_luaentity()
if not ent then return end
ent.growth_scale = 0.7 ent.growth_scale = 0.7
animalia.initialize_api(ent) animalia.initialize_api(ent)
animalia.protect_from_despawn(ent) animalia.protect_from_despawn(ent)
@ -80,7 +81,6 @@ local function register_egg(name, def)
y = pos.y + 1.5, y = pos.y + 1.5,
z = pos.z z = pos.z
}, def.mob .. "_egg_entity") }, def.mob .. "_egg_entity")
local ent = object and object:get_luaentity()
local dir = player:get_look_dir() local dir = player:get_look_dir()
object:set_velocity({ object:set_velocity({
x = dir.x * vel, x = dir.x * vel,
@ -130,7 +130,6 @@ local function mob_storage_use(itemstack, player, pointed)
local plyr_name = player:get_player_name() local plyr_name = player:get_player_name()
local meta = itemstack:get_meta() local meta = itemstack:get_meta()
local mob = meta:get_string("mob") or "" local mob = meta:get_string("mob") or ""
local staticdata = meta:get_string("staticdata") or ""
if mob == "" then if mob == "" then
animalia.protect_from_despawn(ent) animalia.protect_from_despawn(ent)
meta:set_string("mob", ent.name) meta:set_string("mob", ent.name)
@ -321,58 +320,6 @@ minetest.register_craftitem("animalia:bucket_milk", {
groups = {food_milk = 1, flammable = 3}, groups = {food_milk = 1, flammable = 3},
}) })
local 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", { minetest.register_craftitem("animalia:bucket_guano", {
description = "Bucket of Guano", description = "Bucket of Guano",
inventory_image = "animalia_guano_bucket.png", inventory_image = "animalia_guano_bucket.png",
@ -383,7 +330,7 @@ minetest.register_craftitem("animalia:bucket_guano", {
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
if node if node
and node.on_rightclick then and node.on_rightclick then
return node.on_rightclick(pointed_thing.under, under, placer, itemstack) return node.on_rightclick(pos, node, placer, itemstack)
end end
if minetest.is_protected(pos, placer:get_player_name()) then if minetest.is_protected(pos, placer:get_player_name()) then
return return
@ -651,7 +598,7 @@ local steel_ingot = "default:steel_ingot"
minetest.register_on_mods_loaded(function() minetest.register_on_mods_loaded(function()
if minetest.registered_items[steel_ingot] then return end if minetest.registered_items[steel_ingot] then return end
for name, def in pairs(minetest.registered_items) do for name, _ in pairs(minetest.registered_items) do
if name:find("ingot") if name:find("ingot")
and (name:find("steel") and (name:find("steel")
or name:find("iron")) then or name:find("iron")) then

View file

@ -31,6 +31,66 @@ end
is_day() is_day()
-- Player Effects
animalia.player_effects = {}
local function player_effect_step()
for player, data in pairs(animalia.player_effects) do
if player then
local timer = data.timer - 1
animalia.player_effects[player].timer = timer
local func = data.func
func(minetest.get_player_by_name(player))
if timer <= 0 then
animalia.player_effects[player] = nil
end
end
end
minetest.after(1, player_effect_step)
end
player_effect_step()
function animalia.set_player_effect(player_name, effect, timer)
animalia.player_effects[player_name] = {
func = effect,
timer = timer or 5
}
end
-- Create lists of items for reuse
animalia.food_wheat = {}
animalia.food_seeds = {}
animalia.food_crops = {}
minetest.register_on_mods_loaded(function()
if minetest.get_modpath("farming")
and farming.registered_plants then
for _, def in pairs(farming.registered_plants) do
if def.crop then
table.insert(animalia.food_crops, def.crop)
end
end
end
for name 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(animalia.food_wheat, name)
return
end
if name:match(":seed_")
or name:match("_seed") then
table.insert(animalia.food_seeds, name)
return
end
end
end)
-- Load Files
dofile(path.."/api/api.lua") dofile(path.."/api/api.lua")
dofile(path.."/api/behaviors.lua") dofile(path.."/api/behaviors.lua")
dofile(path.."/api/lasso.lua") dofile(path.."/api/lasso.lua")
@ -38,7 +98,7 @@ dofile(path.."/craftitems.lua")
animalia.animals = { animalia.animals = {
"animalia:bat", "animalia:bat",
"animalia:bird", "animalia:song_bird",
"animalia:cat", "animalia:cat",
"animalia:chicken", "animalia:chicken",
"animalia:cow", "animalia:cow",
@ -80,8 +140,8 @@ minetest.register_on_mods_loaded(function()
old_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage) old_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return end if not pos then return end
local name = puncher:is_player() and puncher:get_player_name() local plyr_name = puncher:is_player() and puncher:get_player_name()
local pets = (name and animalia.pets[name]) or {} local pets = (plyr_name and animalia.pets[plyr_name]) or {}
for _, obj in ipairs(pets) do for _, obj in ipairs(pets) do
local ent = obj and obj:get_luaentity() local ent = obj and obj:get_luaentity()
if ent if ent

View file

@ -32,7 +32,6 @@ end
creatura.register_mob("animalia:bat", { creatura.register_mob("animalia:bat", {
-- Engine Props -- Engine Props
visual = "mesh",
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = "animalia_bat.b3d", mesh = "animalia_bat.b3d",
textures = { textures = {
@ -41,16 +40,23 @@ creatura.register_mob("animalia:bat", {
"animalia_bat_3.png", "animalia_bat_3.png",
}, },
makes_footstep_sound = false, makes_footstep_sound = false,
stepheight = 1.1,
-- Creatura Props -- Creatura Props
max_health = 5, max_health = 2,
armor_groups = {fleshy = 100}, armor_groups = {fleshy = 100},
damage = 0, damage = 0,
speed = 6, speed = 4,
tracking_range = 8, tracking_range = 12,
max_boids = 2, max_boids = 3,
despawn_after = 500, despawn_after = 200,
max_fall = 0, max_fall = 0,
sounds = {
random = {
name = "animalia_bat",
gain = 0.5,
distance = 16
}
},
hitbox = { hitbox = {
width = 0.15, width = 0.15,
height = 0.3 height = 0.3
@ -66,11 +72,14 @@ creatura.register_mob("animalia:bat", {
"butterflies:butterfly_white", "butterflies:butterfly_white",
"butterflies:butterfly_violet" "butterflies:butterfly_violet"
}, },
fancy_collide = false,
bouyancy_multiplier = 1,
hydrodynamics_multiplier = 1,
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
roost_action = animalia.action_cling, roost_action = animalia.action_cling,
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:aerial_wander", utility = "animalia:aerial_wander",
@ -81,7 +90,6 @@ creatura.register_mob("animalia:bat", {
local player = creatura.get_nearby_player(self) local player = creatura.get_nearby_player(self)
local plyr_pos = player and not player:get_player_control().sneak and player:get_pos() local plyr_pos = player and not player:get_player_control().sneak and player:get_pos()
if plyr_pos then if plyr_pos then
local trust = self.trust[player:get_player_name() or ""] or 0
local dist = vec_dist(pos, plyr_pos) local dist = vec_dist(pos, plyr_pos)
self._target = player self._target = player
self.is_landed = false self.is_landed = false
@ -116,10 +124,7 @@ creatura.register_mob("animalia:bat", {
end end
} }
}, },
-- Animalia Props
catch_with_net = true,
catch_with_lasso = false,
-- Functions
is_home = function(pos, home_pos) is_home = function(pos, home_pos)
local dist = vec_dist(pos, home_pos) local dist = vec_dist(pos, home_pos)
if dist < 4 then if dist < 4 then
@ -131,6 +136,7 @@ creatura.register_mob("animalia:bat", {
end end
return false return false
end, end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
self.home_position = self:recall("home_position") or nil self.home_position = self:recall("home_position") or nil
@ -142,6 +148,7 @@ creatura.register_mob("animalia:bat", {
get_home_pos(self) get_home_pos(self)
end end
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
@ -184,11 +191,13 @@ creatura.register_mob("animalia:bat", {
end end
end end
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, false) then if animalia.feed(self, clicker, false, false) then
animalia.add_trust(self, clicker, 1) animalia.add_trust(self, clicker, 1)
@ -198,6 +207,7 @@ creatura.register_mob("animalia:bat", {
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })

View file

@ -1,229 +0,0 @@
---------------
-- Song Bird --
---------------
local follows = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
end
end
end)
local random = math.random
local vec_dist = vector.distance
creatura.register_mob("animalia:bird", {
-- Stats
max_health = 5,
armor_groups = {fleshy = 200},
damage = 0,
speed = 4,
tracking_range = 16,
despawn_after = 750,
-- Entity Physics
stepheight = 1.1,
max_fall = 0,
turn_rate = 3,
boid_seperation = 0.4,
-- 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
max_boids = 12,
makes_footstep_sound = true,
catch_with_net = true,
catch_with_lasso = false,
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
wander_action = animalia.action_move_boid,
utility_stack = {
{
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
end
},
{
utility = "animalia:aerial_wander",
step_delay = 0.25,
get_score = function(self)
if not self.is_landed
or self.in_liquid then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:fly_to_land",
get_score = function(self)
if self.is_landed
and not self.touching_ground
and not self.in_liquid
and creatura.sensor_floor(self, 3, true) > 2 then
return 0.3, {self}
end
return 0
end
},
{
utility = "animalia:fly_to_roost",
get_score = function(self)
local pos = self.object:get_pos()
if not pos then return end
local player = creatura.get_nearby_player(self)
if player
and player:get_pos() then
local dist = vector.distance(pos, player:get_pos())
if dist < 3 then
return 0
end
end
local home = not animalia.is_day and self.home_position
if home
and vec_dist(pos, home) < 8 then
return 0.6, {self}
end
return 0
end
}
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
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
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)
animalia.rotate_to_pitch(self)
if self:timer(random(6,12)) then
if animalia.is_day 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 random(4) < 2 then
self.is_landed = not self.is_landed
end
local home = self.home_position
if home
and creatura.get_node_def(home).name ~= "animalia:nest_song_bird" then
local nodes = minetest.find_nodes_in_area_under_air(
{x = home.x, y = home.y - 12, z = home.z},
{x = home.x, y = home.y + 12, z = home.z},
{"animalia:nest_song_bird"}
)
if nodes[1] then
self.home_position = self:memorize("home_position", nodes[1])
end
end
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,
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
return
end
if animalia.set_nametag(self, clicker) then
return
end
end,
on_punch = animalia.punch
})
creatura.register_spawn_egg("animalia:bird", "ae2f2f", "f3ac1c")
minetest.register_abm({
label = "animalia:nest_cleanup",
nodenames = "animalia:nest_song_bird",
interval = 900,
action = function(pos)
minetest.remove_node(pos)
end
})

View file

@ -4,7 +4,7 @@
local random = math.random local random = math.random
local vec_dist = vector.distance local vec_dist, vec_add, vec_sub = vector.distance, vector.add, vector.subtract
local follow = { local follow = {
"animalia:poultry_raw" "animalia:poultry_raw"
@ -17,24 +17,28 @@ if minetest.registered_items["ethereal:fish_raw"] then
} }
end end
local function find_glass_vessel(self)
local pos = self.object:get_pos()
if not pos then return end
local nodes = minetest.find_nodes_in_area(vec_sub(pos, 6), vec_add(pos, 6),
{"vessels:glass_bottle", "vessels:drinking_glass"}) or {}
if #nodes < 1 then return end
return nodes[math.random(#nodes)]
end
local function destroy_glass_vessel(self, pos)
if not minetest.is_protected(pos, "") then
minetest.remove_node(pos)
minetest.add_item(pos, "vessels:glass_fragments")
return true
end
end
creatura.register_mob("animalia:cat", { creatura.register_mob("animalia:cat", {
-- Stats -- Engine Props
max_health = 10,
armor_groups = {fleshy = 200},
damage = 1,
speed = 5,
tracking_range = 24,
turn_rate = 9,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
-- Visuals
mesh = "animalia_cat.b3d",
hitbox = {
width = 0.2,
height = 0.4
},
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = "animalia_cat.b3d",
textures = { textures = {
"animalia_cat_1.png", "animalia_cat_1.png",
"animalia_cat_2.png", "animalia_cat_2.png",
@ -48,22 +52,23 @@ creatura.register_mob("animalia:cat", {
"animalia_cat_ash.png", "animalia_cat_ash.png",
"animalia_cat_birch.png", "animalia_cat_birch.png",
}, },
animations = { use_texture_alpha = false,
stand = {range = {x = 1, y = 39}, speed = 10, frame_blend = 0.3, loop = true}, makes_footstep_sound = false,
walk = {range = {x = 41, y = 59}, speed = 20, frame_blend = 0.3, loop = true}, backface_culling = true,
run = {range = {x = 42, y = 59}, speed = 30, frame_blend = 0.3, loop = true}, glow = 0,
play = {range = {x = 61, y = 79}, speed = 30, frame_blend = 0.3, loop = false},
sit = {range = {x = 81, y = 99}, speed = 10, frame_blend = 0.3, loop = true}, -- Creatura Props
smack = {range = {x = 101, y = 119}, speed = 40, frame_blend = 0.1, loop = true}, max_health = 10,
}, damage = 1,
-- Misc speed = 3,
makes_footstep_sound = true, tracking_range = 16,
flee_puncher = true, max_boids = 0,
catch_with_net = true, despawn_after = 500,
catch_with_lasso = true, max_fall = 0,
stepheight = 1.1,
sounds = { sounds = {
random = { random = {
name = "animalia_cat_idle", name = "animalia_cat",
gain = 0.25, gain = 0.25,
distance = 8 distance = 8
}, },
@ -83,32 +88,35 @@ creatura.register_mob("animalia:cat", {
distance = 8 distance = 8
} }
}, },
follow = follow, hitbox = {
head_data = { width = 0.2,
offset = {x = 0, y = 0.18, z = 0}, height = 0.4
pitch_correction = -20,
pivot_h = 0.65,
pivot_v = 0.65
}, },
-- Function animations = {
activate_func = function(self) stand = {range = {x = 1, y = 60}, speed = 20, frame_blend = 0.3, loop = true},
animalia.initialize_api(self) walk = {range = {x = 70, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
animalia.initialize_lasso(self) run = {range = {x = 100, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
self.interact_sound_cooldown = 0 sit = {range = {x = 130, y = 139}, speed = 10, frame_blend = 0.3, loop = true},
self.trust_cooldown = self:recall("trust_cooldown") or 0 },
self.order = self:recall("order") or "wander" follow = follow,
self.owner = self:recall("owner") or nil drops = {},
self.trust = self:recall("trust") or {}
if self.owner -- Animalia Props
and minetest.get_player_by_name(self.owner) then flee_puncher = true,
if not animalia.pets[self.owner][self.object] then catch_with_net = true,
table.insert(animalia.pets[self.owner], self.object) catch_with_lasso = true,
end head_data = {
end offset = {x = 0, y = 0.14, z = 0},
end, pitch_correction = -25,
pivot_h = 0.4,
pivot_v = 0.4
},
skittish_wander = true,
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_skittish", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
@ -125,11 +133,11 @@ creatura.register_mob("animalia:cat", {
end end
}, },
{ {
utility = "animalia:destroy_nearby_vessel", utility = "animalia:walk_to_pos_and_interact",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
if random(24) < 2 then if random(2) < 2 then
return 0.2, {self} return 0.2, {self, find_glass_vessel, destroy_glass_vessel, nil, 10}
end end
return 0 return 0
end end
@ -217,6 +225,23 @@ creatura.register_mob("animalia:cat", {
end end
} }
}, },
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.interact_sound_cooldown = 0
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
end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self, 0.75, 0.75)
@ -229,38 +254,39 @@ creatura.register_mob("animalia:cat", {
end end
end end
end, end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then death_func = animalia.death_func,
self:initiate_utility("animalia:die", self)
deactivate_func = function(self)
if self.owner then
for i, object in ipairs(animalia.pets[self.owner] or {}) do
if object == self.object then
animalia.pets[self.owner][i] = nil
end
end
end
if self.enemies
and self.enemies[1]
and self.memorize then
self.enemies[1] = nil
self.enemies = self:memorize("enemies", self.enemies)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
local item_name = clicker:get_wielded_item():get_name() local item_name = clicker:get_wielded_item():get_name()
if item_name == "animalia:net" then return end if item_name == "animalia:net" then return end
local trust = self.trust[clicker:get_player_name()] or 0 local trust = self.trust[clicker:get_player_name()] or 0
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return end if not pos then return end
pos.y = pos.y + self.height * 0.5
local minppos = vector.add(pos, 1)
local maxppos = vector.subtract(pos, 1)
if animalia.feed(self, clicker, true, true) then if animalia.feed(self, clicker, true, true) then
if self.trust_cooldown <= 0 animalia.add_trust(self, clicker, 1)
and trust < 10 then animalia.particle_spawner(pos, "creatura_particle_green.png", "float")
self.trust[clicker:get_player_name()] = trust + 1
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 return
end end
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
-- Initiate trust
if not self.trust[clicker:get_player_name()] then
self.trust[clicker:get_player_name()] = 0
self:memorize("trust", self.trust)
end
-- Purr to indicate trust level (louder = more trust) -- Purr to indicate trust level (louder = more trust)
if clicker:get_player_control().sneak then if clicker:get_player_control().sneak then
if self.interact_sound_cooldown <= 0 then if self.interact_sound_cooldown <= 0 then
@ -288,49 +314,35 @@ creatura.register_mob("animalia:cat", {
end end
local order = self.order local order = self.order
if order == "wander" then if order == "wander" then
minetest.chat_send_player(clicker:get_player_name(), "Wolf is following") minetest.chat_send_player(clicker:get_player_name(), "Cat is following")
self.order = "follow" self.order = "follow"
self:initiate_utility("animalia:follow_player", self, clicker, true) self:initiate_utility("animalia:follow_player", self, clicker, true)
self:set_utility_score(0.7) self:set_utility_score(0.7)
elseif order == "follow" then elseif order == "follow" then
minetest.chat_send_player(clicker:get_player_name(), "Wolf is sitting") minetest.chat_send_player(clicker:get_player_name(), "Cat is sitting")
self.order = "sit" self.order = "sit"
self:initiate_utility("animalia:stay", self) self:initiate_utility("animalia:stay", self)
self:set_utility_score(0.5) self:set_utility_score(0.5)
else else
minetest.chat_send_player(clicker:get_player_name(), "Wolf is wandering") minetest.chat_send_player(clicker:get_player_name(), "Cat is wandering")
self.order = "wander" self.order = "wander"
self:set_utility_score(0) self:set_utility_score(0)
end end
self:memorize("order", self.order) self:memorize("order", self.order)
end end
end, end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage) 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) creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
self:initiate_utility("animalia:flee_from_player", self, puncher) self:initiate_utility("animalia:flee_from_player", self, puncher)
self:set_utility_score(1) self:set_utility_score(1)
if not self.trust[puncher:get_player_name()] then animalia.add_trust(self, puncher, -1)
self.trust[puncher:get_player_name()] = 0
else
local trust = self.trust[puncher:get_player_name()]
self.trust[puncher:get_player_name()] = trust - 1
end
local pos = self.object:get_pos() local pos = self.object:get_pos()
pos = vector.new(pos.x, pos.y + 0.5, pos.z) animalia.particle_spawner(pos, "creatura_particle_red.png", "float")
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 then
for i, object in ipairs(animalia.pets[self.owner] or {}) do
if object == self.object then
animalia.pets[self.owner][i] = nil
end
end
end
end end
}) })
creatura.register_spawn_egg("animalia:cat", "db9764" ,"cf8d5a") creatura.register_spawn_item("animalia:cat", {
col1 = "db9764",
col2 = "cf8d5a"
})

View file

@ -2,36 +2,10 @@
-- Chicken -- -- Chicken --
------------- -------------
local follows = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
end
end
end)
creatura.register_mob("animalia:chicken", { creatura.register_mob("animalia:chicken", {
-- Stats -- Engine Props
max_health = 5, visual_size = {x = 10, y = 10},
armor_groups = {fleshy = 150},
damage = 0,
speed = 4,
tracking_range = 4,
despawn_after = 1500,
-- Entity Physics
stepheight = 1.1,
max_fall = 8,
turn_rate = 7,
-- Visuals
mesh = "animalia_chicken.b3d", mesh = "animalia_chicken.b3d",
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 7, y = 7},
female_textures = { female_textures = {
"animalia_chicken_1.png", "animalia_chicken_1.png",
"animalia_chicken_2.png", "animalia_chicken_2.png",
@ -43,21 +17,21 @@ creatura.register_mob("animalia:chicken", {
"animalia_rooster_3.png" "animalia_rooster_3.png"
}, },
child_textures = {"animalia_chicken_child.png"}, child_textures = {"animalia_chicken_child.png"},
animations = {
stand = {range = {x = 1, y = 39}, speed = 20, frame_blend = 0.3, loop = true},
walk = {range = {x = 41, y = 59}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 41, y = 59}, speed = 45, frame_blend = 0.3, loop = true},
eat = {range = {x = 61, y = 89}, speed = 45, frame_blend = 0.3, loop = true},
fall = {range = {x = 91, y = 99}, speed = 70, frame_blend = 0.3, loop = true}
},
-- Misc
makes_footstep_sound = true, makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true, -- Creatura Props
catch_with_lasso = true, max_health = 5,
armor_groups = {fleshy = 100},
damage = 0,
speed = 2,
tracking_range = 8,
max_boids = 3,
despawn_after = 500,
max_fall = 0,
stepheight = 1.1,
sounds = { sounds = {
random = { random = {
name = "animalia_chicken_idle", name = "animalia_chicken",
gain = 0.5, gain = 0.5,
distance = 8 distance = 8
}, },
@ -72,11 +46,28 @@ creatura.register_mob("animalia:chicken", {
distance = 8 distance = 8
} }
}, },
hitbox = {
width = 0.25,
height = 0.5
},
animations = {
stand = {range = {x = 1, y = 39}, speed = 20, frame_blend = 0.3, loop = true},
walk = {range = {x = 41, y = 59}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 41, y = 59}, speed = 45, frame_blend = 0.3, loop = true},
eat = {range = {x = 61, y = 89}, speed = 45, frame_blend = 0.3, loop = true},
fall = {range = {x = 91, y = 99}, speed = 70, frame_blend = 0.3, loop = true}
},
follow = animalia.food_seeds,
drops = { drops = {
{name = "animalia:poultry_raw", min = 1, max = 3, chance = 1}, {name = "animalia:poultry_raw", min = 1, max = 3, chance = 1},
{name = "animalia:feather", min = 1, max = 3, chance = 2} {name = "animalia:feather", min = 1, max = 3, chance = 2}
}, },
follow = follows,
-- Animalia Props
group_wander = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
head_data = { head_data = {
offset = {x = 0, y = 0.45, z = 0}, offset = {x = 0, y = 0.45, z = 0},
pitch_correction = 40, pitch_correction = 40,
@ -85,31 +76,11 @@ creatura.register_mob("animalia:chicken", {
}, },
move_chance = 2, move_chance = 2,
idle_time = 1, idle_time = 1,
-- Function
add_child = function(self) -- Functions
local pos = self.object:get_pos()
if not pos then return end
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",
})
local object = minetest.add_entity(pos, self.name)
local ent = object:get_luaentity()
ent.growth_scale = 0.7
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_group", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
@ -139,10 +110,23 @@ creatura.register_mob("animalia:chicken", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
add_child = function(self)
local pos = self.object:get_pos()
if not pos then return end
animalia.particle_spawner(pos, "animalia_egg_fragment.png", "splash", pos, pos)
local object = minetest.add_entity(pos, self.name)
local ent = object:get_luaentity()
ent.growth_scale = 0.7
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self, 0.75, 0.75)
@ -159,20 +143,24 @@ creatura.register_mob("animalia:chicken", {
animalia.random_drop_item(self, "animalia:chicken_egg", 10) animalia.random_drop_item(self, "animalia:chicken_egg", 10)
end end
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
end end
if animalia.set_nametag(self, clicker) then animalia.set_nametag(self, clicker)
return
end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:chicken", "c6c6c6", "d22222") creatura.register_spawn_item("animalia:chicken", {
col1 = "c6c6c6",
col2 = "d22222"
})

View file

@ -4,18 +4,6 @@
local random = math.random local random = math.random
local follows = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_craftitems) do
if (name:match(":wheat")
or minetest.get_item_group(name, "food_wheat") > 0)
and not tonumber(name:sub(-1))
and not name:find("seed") then
table.insert(follows, name)
end
end
end)
creatura.register_mob("animalia:cow", { creatura.register_mob("animalia:cow", {
-- Engine Props -- Engine Props
@ -42,17 +30,35 @@ creatura.register_mob("animalia:cow", {
"animalia_cow_4.png", "animalia_cow_4.png",
"animalia_cow_5.png" "animalia_cow_5.png"
}, },
stepheight = 1.1, makes_footstep_sound = true,
-- Creatura Props -- Creatura Props
max_health = 20, max_health = 20,
armor_groups = {fleshy = 100}, armor_groups = {fleshy = 100},
damage = 0, damage = 0,
speed = 4, speed = 2,
tracking_range = 16, tracking_range = 10,
despawn_after = 1000, max_boids = 0,
despawn_after = 500,
max_fall = 3, max_fall = 3,
stepheight = 1.1, stepheight = 1.1,
sound = {}, sounds = {
random = {
name = "animalia_cow",
gain = 0.5,
distance = 8
},
hurt = {
name = "animalia_cow_hurt",
gain = 0.5,
distance = 8
},
death = {
name = "animalia_cow_death",
gain = 0.5,
distance = 8
}
},
hitbox = { hitbox = {
width = 0.5, width = 0.5,
height = 1 height = 1
@ -62,14 +68,13 @@ creatura.register_mob("animalia:cow", {
walk = {range = {x = 71, y = 89}, speed = 20, frame_blend = 0.3, loop = true}, walk = {range = {x = 71, y = 89}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true}, run = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
}, },
follow = follows, follow = animalia.food_wheat,
drops = { drops = {
{name = "animalia:beef_raw", min = 1, max = 3, chance = 1}, {name = "animalia:beef_raw", min = 1, max = 3, chance = 1},
{name = "animalia:leather", min = 1, max = 3, chance = 2} {name = "animalia:leather", min = 1, max = 3, chance = 2}
}, },
fancy_collide = false, fancy_collide = false,
bouyancy_multiplier = 1,
hydrodynamics_multiplier = 1,
-- Animalia Props -- Animalia Props
flee_puncher = true, flee_puncher = true,
catch_with_net = true, catch_with_net = true,
@ -79,12 +84,14 @@ creatura.register_mob("animalia:cow", {
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt" ["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
}, },
head_data = { head_data = {
offset = {x = 0, y = 0.8, z = 0.0}, offset = {x = 0, y = 0.5, z = 0.0},
pitch_correction = -65, pitch_correction = -40,
pivot_h = 0.75, pivot_h = 0.75,
pivot_v = 1 pivot_v = 1
}, },
wander_action = animalia.action_boid_move,
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander", utility = "animalia:wander",
@ -127,12 +134,13 @@ creatura.register_mob("animalia:cow", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
-- Functions
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
self.collected = self:recall("collected") or false self.collected = self:recall("collected") or false
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self, 0.75, 0.75)
@ -140,18 +148,19 @@ creatura.register_mob("animalia:cow", {
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
animalia.random_sound(self) animalia.random_sound(self)
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true)
return or animalia.set_nametag(self, clicker) then
end
if animalia.set_nametag(self, clicker) then
return return
end end
local tool = clicker:get_wielded_item() local tool = clicker:get_wielded_item()
local name = clicker:get_player_name() local name = clicker:get_player_name()
@ -183,7 +192,11 @@ creatura.register_mob("animalia:cow", {
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:cow", "cac3a1" ,"464438") creatura.register_spawn_item("animalia:cow", {
col1 = "cac3a1",
col2 = "464438"
})

View file

@ -1,38 +1,74 @@
---------- ---------
-- Wolf -- -- Fox --
---------- ---------
local vec_dir, vec_dist = vector.direction, vector.direction
local dir2yaw = minetest.dir_to_yaw
local function get_food_pos(self)
local _, pos = animalia.get_dropped_food(self)
return pos
end
local function eat_dropped_food(self)
local pos = self.object:get_pos()
if not pos then return end
local food = animalia.get_dropped_food(self, nil, self.width + 1)
local food_ent = food and food:get_luaentity()
if food_ent then
local food_pos = food:get_pos()
local stack = ItemStack(food_ent.itemstring)
if stack
and stack:get_count() > 1 then
stack:take_item()
food_ent.itemstring = stack:to_string()
else
food:remove()
end
self.object:set_yaw(dir2yaw(vec_dir(pos, food_pos)))
animalia.add_food_particle(self, stack:get_name())
if self.on_eat_drop then
self:on_eat_drop()
end
return true
end
end
creatura.register_mob("animalia:fox", { creatura.register_mob("animalia:fox", {
-- Stats -- Engine Props
max_health = 15, visual_size = {x = 10, y = 10},
armor_groups = {fleshy = 100},
damage = 4,
speed = 5,
tracking_range = 24,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
max_fall = 3,
-- Visuals
mesh = "animalia_fox.b3d", mesh = "animalia_fox.b3d",
textures = {
"animalia_fox_1.png"
},
makes_footstep_sound = false,
-- Creatura Props
max_health = 10,
armor_groups = {fleshy = 100},
damage = 2,
speed = 4,
tracking_range = 16,
max_boids = 0,
despawn_after = 500,
stepheight = 1.1,
sound = {},
hitbox = { hitbox = {
width = 0.35, width = 0.35,
height = 0.7 height = 0.5
},
visual_size = {x = 10, y = 10},
textures = {
"animalia_fox_1.png",
}, },
animations = { animations = {
stand = {range = {x = 1, y = 39}, speed = 10, frame_blend = 0.3, loop = true}, stand = {range = {x = 1, y = 39}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 41, y = 59}, speed = 30, frame_blend = 0.3, loop = true}, walk = {range = {x = 41, y = 59}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 41, y = 59}, speed = 45, frame_blend = 0.3, loop = true}, run = {range = {x = 41, y = 59}, speed = 45, frame_blend = 0.3, loop = true},
}, },
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
follow = { follow = {
"animalia:rat_raw", "animalia:rat_raw",
"animalia:mutton_raw", "animalia:mutton_raw",
@ -40,19 +76,23 @@ creatura.register_mob("animalia:fox", {
"animalia:porkchop_raw", "animalia:porkchop_raw",
"animalia:poultry_raw" "animalia:poultry_raw"
}, },
-- Animalia Props
skittish_wander = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
head_data = { head_data = {
offset = {x = 0, y = 0.18, z = 0}, offset = {x = 0, y = 0.18, z = 0},
pitch_correction = -67, pitch_correction = -67,
pivot_h = 0.65, pivot_h = 0.65,
pivot_v = 0.65 pivot_v = 0.65
}, },
-- Function
on_eat_drop = function(self) -- Functions
animalia.protect_from_despawn(self)
end,
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_skittish", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
@ -89,7 +129,7 @@ creatura.register_mob("animalia:fox", {
if not tgt_pos then self._puncher = nil return 0 end if not tgt_pos then self._puncher = nil return 0 end
local sneaking = target:get_player_control().sneak local sneaking = target:get_player_control().sneak
if not sneaking then if not sneaking then
local dist = vector.distance(pos, tgt_pos) local dist = vec_dist(pos, tgt_pos)
local score = (self.tracking_range - dist) / self.tracking_range local score = (self.tracking_range - dist) / self.tracking_range
self._puncher = target self._puncher = target
return score / 2, {self, target} return score / 2, {self, target}
@ -99,16 +139,10 @@ creatura.register_mob("animalia:fox", {
end end
}, },
{ {
utility = "animalia:walk_to_food", utility = "animalia:walk_to_pos_and_interact",
get_score = function(self) get_score = function(self)
local cooldown = self.eat_cooldown or 0 if math.random(14) < 2 then
if cooldown > 0 then return 0.7, {self, get_food_pos, eat_dropped_food, nil, 12}
self.eat_cooldown = cooldown - 1
return 0
end
local food_item = animalia.get_dropped_food(self)
if food_item then
return 0.7, {self, food_item}
end end
return 0 return 0
end end
@ -137,33 +171,38 @@ creatura.register_mob("animalia:fox", {
end end
} }
}, },
on_eat_drop = function(self)
animalia.protect_from_despawn(self)
end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.5, 0.75) animalia.head_tracking(self, 0.5, 0.75)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
end, end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then death_func = animalia.death_func,
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if not clicker:is_player() then return end if animalia.feed(self, clicker, true, true) then
local name = clicker:get_player_name()
local passive = true
if animalia.feed(self, clicker, passive, passive) then
return return
end end
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:fox", "d0602d" ,"c9c9c9") creatura.register_spawn_item("animalia:fox", {
col1 = "d0602d",
col2 = "c9c9c9"
})

View file

@ -8,67 +8,47 @@ local vec_add = vector.add
local vec_dist = vector.distance local vec_dist = vector.distance
local vec_sub = vector.subtract local vec_sub = vector.subtract
creatura.register_mob("animalia:frog", { local function poison_effect(object)
-- Stats object:punch(object, 1.0, {
max_health = 5, full_punch_interval = 1.0,
armor_groups = {fleshy = 200}, damage_groups = {fleshy = 1},
damage = 0, })
speed = 4, end
tracking_range = 16,
despawn_after = 2500, local hitboxes = {
-- Entity Physics {-0.25, 0, -0.25, 0.2, 0.4, 0.25},
stepheight = 1.1, {-0.4, 0, -0.4, 0.4, 0.5, 0.4},
max_fall = 0, {-0.15, 0, -0.15, 0.15, 0.3, 0.15}
turn_rate = 10, }
bouyancy_multiplier = 0,
hydrodynamics_multiplier = 0.3, local animations = {
-- 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}, 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}, 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}, 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}, walk = {range = {x = 50, y = 80}, speed = 50, frame_blend = 0.3, loop = true},
run = {range = {x = 50, y = 80}, speed = 60, frame_blend = 0.3, loop = true} run = {range = {x = 50, y = 80}, speed = 60, frame_blend = 0.3, loop = true}
}, },
-- Misc {
makes_footstep_sound = true, stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
flee_puncher = true, walk = {range = {x = 50, y = 79}, speed = 20, frame_blend = 0.3, loop = true},
catch_with_net = true, run = {range = {x = 50, y = 79}, speed = 30, frame_blend = 0.3, loop = true},
catch_with_lasso = true, warn = {range = {x = 90, y = 129}, speed = 30, frame_blend = 0.3, loop = true},
sounds = { punch = {range = {x = 140, y = 160}, speed = 30, frame_blend = 0.1, loop = false},
random = { float = {range = {x = 170, y = 209}, speed = 10, frame_blend = 0.3, loop = true},
name = "animalia_frog", swim = {range = {x = 220, y = 239}, speed = 20, frame_blend = 0.3, loop = true}
gain = 0.5,
distance = 32,
variations = 3
}
}, },
follow = { {
"butterflies:butterfly_red", stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
"butterflies:butterfly_white", walk = {range = {x = 50, y = 69}, speed = 30, frame_blend = 0.3, loop = true},
"butterflies:butterfly_violet" run = {range = {x = 50, y = 69}, speed = 40, frame_blend = 0.3, loop = true},
}, float = {range = {x = 80, y = 119}, speed = 10, frame_blend = 0.3, loop = true},
head_data = { swim = {range = {x = 130, y = 149}, speed = 20, frame_blend = 0.3, loop = true}
offset = {x = 0, y = 0.43, z = 0}, }
pitch_correction = -15, }
pivot_h = 0.3,
pivot_v = 0.3 local utility_stacks = {
}, { -- Tree Frog
-- Function
utility_stack = {
{ {
utility = "animalia:wander", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
@ -117,7 +97,7 @@ creatura.register_mob("animalia:frog", {
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
if not self.in_liquid if not self.in_liquid
and self.growth_scale <= 0.6 then and self.growth_scale < 0.8 then
return 1, {self} return 1, {self}
end end
return 0 return 0
@ -159,38 +139,318 @@ creatura.register_mob("animalia:frog", {
end end
} }
}, },
{ -- Bull Frog
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
},
{
utility = "animalia:aquatic_wander",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:walk_to_food",
get_score = function(self)
local cooldown = self.eat_cooldown or 0
if cooldown > 0 then
self.eat_cooldown = cooldown - 1
return 0
end
local food_item = animalia.get_dropped_food(self)
if food_item then
return 0.3, {self, food_item}
end
return 0
end
},
{
utility = "animalia:warn_attack_target",
get_score = function(self)
local target = creatura.get_nearby_player(self) or creatura.get_nearby_object(self, "animalia:rat")
if target then
if target:is_player() then
local trust = self.trust[target:get_player_name()] or 0
if trust > 5 then
return 0
end
end
return 0.4, {self, target}
end
return 0
end
},
{
utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name)
and self.in_liquid then
return 1, {self}
end
return 0
end
},
{
utility = "animalia:flop",
step_delay = 0.25,
get_score = function(self)
if not self.in_liquid
and self.growth_scale < 0.8 then
return 1, {self}
end
return 0
end
},
{
utility = "animalia:run_to_pos",
get_score = function(self)
if self.in_liquid then return 0 end
local pos = self.object:get_pos()
if not pos then return end
local water = minetest.find_nodes_in_area(vec_sub(pos, 1.5), vec_add(pos, 1.5), {"group:water"})
if not water[1] then return 0 end
local player = self._target
local plyr_name = player and player:is_player() and player:get_player_name()
if plyr_name then
local plyr_pos = player and player:get_pos()
local trust = self.trust[plyr_name] or 0
return (10 - (vec_dist(pos, plyr_pos) + trust)) * 0.1, {self, water[1]}
end
return 0
end
}
},
{
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
},
{
utility = "animalia:aquatic_wander",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name)
and self.in_liquid then
return 1, {self}
end
return 0
end
},
{
utility = "animalia:flop",
step_delay = 0.25,
get_score = function(self)
if not self.in_liquid
and self.growth_scale < 0.8 then
return 1, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
if self.in_liquid then return 0 end
local pos = self.object:get_pos()
if not pos then return end
local target = self._puncher or self._target or creatura.get_nearby_player(self)
local tgt_pos = target and target:get_pos()
local plyr_name = (target and target:is_player() and target:get_player_name()) or ""
if tgt_pos then
local trust = self.trust[plyr_name] or 0
self._target = target -- stored to memory to avoid calling get_nearby_player again
return (10 - (vec_dist(pos, tgt_pos) + trust)) * 0.1, {self, target}
end
return 0
end
},
{
utility = "animalia:run_to_pos",
get_score = function(self)
if self.in_liquid then return 0 end
local pos = self.object:get_pos()
if not pos then return end
local water = minetest.find_nodes_in_area(vec_sub(pos, 1.5), vec_add(pos, 1.5), {"group:water"})
if not water[1] then return 0 end
local player = self._target
local plyr_name = player and player:is_player() and player:get_player_name()
if plyr_name then
local plyr_pos = player and player:get_pos()
local trust = self.trust[plyr_name] or 0
return (10 - (vec_dist(pos, plyr_pos) + trust)) * 0.1, {self, water[1]}
end
return 0
end
}
}
}
local head_data = {
{
offset = {x = 0, y = 0.43, z = 0},
pitch_correction = -15,
pivot_h = 0.3,
pivot_v = 0.3
},
{
offset = {x = 0, y = 0.50, z = 0},
pitch_correction = -20,
pivot_h = 0.3,
pivot_v = 0.3
},
{
offset = {x = 0, y = 0.25, z = 0},
pitch_correction = -20,
pivot_h = 0.3,
pivot_v = 0.3
}
}
creatura.register_mob("animalia:frog", {
-- Engine Props
visual_size = {x = 10, y = 10},
meshes = {
"animalia_frog.b3d",
"animalia_bull_frog.b3d",
"animalia_dart_frog.b3d"
},
child_mesh = "animalia_tadpole.b3d",
mesh_textures = {
{
"animalia_tree_frog.png"
},
{
"animalia_bull_frog.png"
},
{
"animalia_dart_frog_1.png",
"animalia_dart_frog_2.png",
"animalia_dart_frog_3.png"
}
},
child_textures = {
"animalia_tadpole.png"
},
makes_footstep_sound = true,
-- Creatura Props
max_health = 5,
armor_groups = {fleshy = 100},
damage = 2,
max_breath = 0,
speed = 2,
tracking_range = 8,
max_boids = 0,
despawn_after = 300,
max_fall = 0,
stepheight = 1.1,
sound = {},
hitbox = {
width = 0.15,
height = 0.3
},
animations = {},
follow = {
"animalia:rat_raw"
},
drops = {},
fancy_collide = false,
bouyancy_multiplier = 0,
hydrodynamics_multiplier = 0.3,
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
head_data = {},
-- Functions
utility_stack = {},
on_grown = function(self)
local mesh_no = self.mesh_no
self.animations = animations[mesh_no]
self.utility_stack = utility_stacks[mesh_no]
self.head_data = head_data[mesh_no]
self.object:set_properties({
collisionbox = hitboxes[mesh_no]
})
end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.trust = self:recall("trust") or {} self.trust = self:recall("trust") or {}
for i = 1, 15 do
local frame = 120 + i local mesh_no = self.mesh_no
local anim = {range = {x = frame, y = frame}, speed = 1, frame_blend = 0.3, loop = false}
self.animations["tongue_" .. i] = anim -- Set Species Properties
if self.growth_scale >= 0.8 then
self.animations = animations[mesh_no]
self.utility_stack = utility_stacks[mesh_no]
self.object:set_properties({
collisionbox = hitboxes[mesh_no]
})
else
self.animations = {
swim = {range = {x = 1, y = 19}, speed = 20, frame_blend = 0.1, loop = true}
}
self.utility_stack = utility_stacks[1]
end
self.head_data = head_data[mesh_no]
if mesh_no == 1 then
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
elseif mesh_no == 2 then
self.object:set_armor_groups({fleshy = 50})
end end
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.2, 0.2) animalia.head_tracking(self, 0.2, 0.2)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self:timer(random(5, 15)) then if self:timer(random(5, 15)) then
self:play_sound("random") self:play_sound("random")
end 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, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if self.mesh_no ~= 2 then return end
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
animalia.add_trust(self, clicker, 1) animalia.add_trust(self, clicker, 1)
return return
@ -199,11 +459,21 @@ creatura.register_mob("animalia:frog", {
return return
end end
end, end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage) 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) creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
self.trust[puncher:get_player_name()] = 0 local name = puncher:is_player() and puncher:get_player_name()
self:memorize("trust", self.trust) if name then
self.trust[name] = 0
self:memorize("trust", self.trust)
if self.mesh_no == 3 then
animalia.set_player_effect(name, poison_effect, 3)
end
end
end end
}) })
creatura.register_spawn_egg("animalia:frog", "67942e", "294811") creatura.register_spawn_item("animalia:frog", {
col1 = "67942e",
col2 = "294811"
})

View file

@ -65,31 +65,16 @@ local function set_pattern(self)
local color_no = self:recall("color_no") or self:memorize("color_no", random(#colors)) local color_no = self:recall("color_no") or self:memorize("color_no", random(#colors))
if not colors[color_no] then return end if not colors[color_no] then return end
local pattern = "(" .. patterns[pattern_no] .. "^[mask:" .. colors[color_no] .. ")" local pattern = "(" .. patterns[pattern_no] .. "^[mask:" .. colors[color_no] .. ")"
local texture = self.object:get_properties().textures[1] local texture = self.textures[self.texture_no]
self.object:set_properties({ self.object:set_properties({
textures = {texture .. "^" .. pattern} textures = {texture .. "^" .. pattern}
}) })
end end
creatura.register_mob("animalia:horse", { creatura.register_mob("animalia:horse", {
-- Stats -- Engine Props
max_health = 40,
armor_groups = {fleshy = 100},
damage = 0,
speed = 10,
tracking_range = 24,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
turn_rate = 8,
boid_seperation = 1.5,
-- Visuals
mesh = "animalia_horse.b3d",
hitbox = {
width = 0.65,
height = 1.95
},
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = "animalia_horse.b3d",
textures = { textures = {
"animalia_horse_1.png", "animalia_horse_1.png",
"animalia_horse_2.png", "animalia_horse_2.png",
@ -98,19 +83,18 @@ creatura.register_mob("animalia:horse", {
"animalia_horse_5.png", "animalia_horse_5.png",
"animalia_horse_6.png" "animalia_horse_6.png"
}, },
animations = {
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 71, y = 89}, speed = 25, frame_blend = 0.3, loop = true},
run = {range = {x = 101, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
punch_aoe = {range = {x = 161, y = 180}, speed = 30, frame_blend = 0.2, loop = false},
rear = {range = {x = 131, y = 150}, speed = 20, frame_blend = 0.2, loop = false},
eat = {range = {x = 191, y = 220}, speed = 30, frame_blend = 0.3, loop = false}
},
-- Misc
makes_footstep_sound = true, makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true, -- Creatura Props
catch_with_lasso = true, max_health = 40,
armor_groups = {fleshy = 100},
damage = 8,
speed = 10,
tracking_range = 16,
max_boids = 7,
despawn_after = 1000,
max_fall = 4,
stepheight = 1.2,
sounds = { sounds = {
alter_child_pitch = true, alter_child_pitch = true,
random = { random = {
@ -129,10 +113,27 @@ creatura.register_mob("animalia:horse", {
distance = 8 distance = 8
} }
}, },
hitbox = {
width = 0.65,
height = 1.95
},
animations = {
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 71, y = 89}, speed = 25, frame_blend = 0.3, loop = true},
run = {range = {x = 101, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
punch_aoe = {range = {x = 161, y = 180}, speed = 30, frame_blend = 0.2, loop = false},
rear = {range = {x = 131, y = 150}, speed = 20, frame_blend = 0.2, loop = false},
eat = {range = {x = 191, y = 220}, speed = 30, frame_blend = 0.3, loop = false}
},
follow = follows,
drops = { drops = {
{name = "animalia:leather", min = 1, max = 4, chance = 2} {name = "animalia:leather", min = 1, max = 4, chance = 2}
}, },
follow = follows, fancy_collide = false,
-- Animalia Props
catch_with_net = true,
catch_with_lasso = true,
consumable_nodes = { consumable_nodes = {
["default:dirt_with_grass"] = "default:dirt", ["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt" ["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
@ -144,30 +145,6 @@ creatura.register_mob("animalia:horse", {
pivot_h = 1, pivot_h = 1,
pivot_v = 1.75 pivot_v = 1.75
}, },
-- Function
add_child = function(self, mate)
local pos = self.object:get_pos()
if not pos then return end
local obj = minetest.add_entity(pos, self.name)
local ent = obj and obj:get_luaentity()
if not ent then return end
ent.growth_scale = 0.7
local tex_no = self.texture_no
local mate_ent = mate and mate:get_luaentity()
if not mate_ent then return end
if random(2) < 2 then
tex_no = mate_ent.texture_no
end
ent:memorize("texture_no", tex_no)
ent:memorize("speed", random(mate_ent.speed, self.speed))
ent:memorize("jump_power", random(mate_ent.jump_power, self.jump_power))
ent:memorize("max_health", random(mate_ent.max_health, self.max_health))
ent.speed = ent:recall("speed")
ent.jump_power = ent:recall("jump_power")
ent.max_health = ent:recall("max_health")
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_group", utility = "animalia:wander_group",
@ -244,6 +221,60 @@ creatura.register_mob("animalia:horse", {
end end
} }
}, },
-- Functions
set_saddle = function(self, saddle)
if 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}
}
else
local pos = self.object:get_pos()
if not pos then return end
self.saddled = self:memorize("saddled", false)
set_pattern(self)
self.drops = {
{name = "animalia:leather", chance = 2, min = 1, max = 4}
}
minetest.add_item(pos, "animalia:saddle")
end
end,
add_child = function(self, mate)
local pos = self.object:get_pos()
if not pos then return end
local obj = minetest.add_entity(pos, self.name)
local ent = obj and obj:get_luaentity()
if not ent then return end
ent.growth_scale = 0.7
local tex_no = self.texture_no
local mate_ent = mate and mate:get_luaentity()
if mate_ent
or not mate_ent.speed
or not mate_ent.jump_power
or not mate_ent.max_health then
return
end
if random(2) < 2 then
tex_no = mate_ent.texture_no
end
ent:memorize("texture_no", tex_no)
ent:memorize("speed", random(mate_ent.speed, self.speed))
ent:memorize("jump_power", random(mate_ent.jump_power, self.jump_power))
ent:memorize("max_health", random(mate_ent.max_health, self.max_health))
ent.speed = ent:recall("speed")
ent.jump_power = ent:recall("jump_power")
ent.max_health = ent:recall("max_health")
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
@ -258,16 +289,10 @@ creatura.register_mob("animalia:horse", {
self:memorize("speed", self.speed) self:memorize("speed", self.speed)
self:memorize("jump_power", self.jump_power) self:memorize("jump_power", self.jump_power)
if self.saddled then if self.saddled then
local texture = self.object:get_properties().textures[1] self:set_saddle(true)
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}
}
end end
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self) animalia.head_tracking(self)
@ -275,48 +300,53 @@ creatura.register_mob("animalia:horse", {
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
animalia.random_sound(self) animalia.random_sound(self)
end, end,
death_func = function(self) death_func = function(self)
if self.rider then
animalia.mount(self, self.rider)
end
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
end end
local owner = self.owner
local name = clicker and clicker:get_player_name()
if owner and name ~= owner then return end
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
local tool = clicker:get_wielded_item() local wielded_name = clicker:get_wielded_item():get_name()
local tool_name = clicker:get_wielded_item():get_name() if wielded_name == "" then
if self.owner
and self.owner == clicker:get_player_name() then
if self.saddled
and tool_name == "" then
animalia.mount(self, clicker, {rot = {x = -75, y = 180, z = 0}, pos = {x = 0, y = 0.6, 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.owner
and tool_name == "" then
animalia.mount(self, clicker, {rot = {x = -75, y = 180, z = 0}, pos = {x = 0, y = 0.6, z = 0.5}}) animalia.mount(self, clicker, {rot = {x = -75, y = 180, z = 0}, pos = {x = 0, y = 0.6, z = 0.5}})
if self.saddled then
self:initiate_utility("animalia:mount", self, clicker)
end
return
end
if wielded_name == "animalia:saddle" then
self:set_saddle(true)
end end
end, end,
on_punch = function(self, puncher, ...) on_punch = function(self, puncher, ...)
if self.rider and puncher == self.rider then return end if self.rider and puncher == self.rider then return end
local name = puncher:is_player() and puncher:get_player_name()
if name
and name == self.owner
and puncher:get_player_control().sneak then
self:set_saddle(false)
return
end
animalia.punch(self, puncher, ...) animalia.punch(self, puncher, ...)
end end
}) })
creatura.register_spawn_egg("animalia:horse", "ebdfd8" ,"653818") creatura.register_spawn_item("animalia:horse", {
col1 = "ebdfd8",
col2 = "653818"
})

View file

@ -2,18 +2,7 @@
-- Owl -- -- Owl --
--------- ---------
local follows = {} local abs = math.abs
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
end
end
end)
local random = math.random
local vec_dist = vector.distance local vec_dist = vector.distance
@ -42,46 +31,51 @@ local function get_home_pos(self)
end end
creatura.register_mob("animalia:owl", { creatura.register_mob("animalia:owl", {
-- Stats -- Engine Props
max_health = 10, visual_size = {x = 10, y = 10},
armor_groups = {fleshy = 100},
damage = 2,
speed = 5,
tracking_range = 32,
despawn_after = 1000,
-- Entity Physics
stepheight = 1.1,
max_fall = 0,
turn_rate = 4,
-- Visuals
mesh = "animalia_owl.b3d", mesh = "animalia_owl.b3d",
textures = {
"animalia_owl.png"
},
makes_footstep_sound = false,
-- Creatura Props
max_health = 10,
damage = 2,
speed = 4,
tracking_range = 16,
max_boids = 0,
despawn_after = 500,
max_fall = 0,
sound = {}, -- TODO
hitbox = { hitbox = {
width = 0.15, width = 0.15,
height = 0.3 height = 0.3
}, },
visual_size = {x = 10, y = 10},
textures = {
"animalia_owl.png"
},
animations = { animations = {
stand = {range = {x = 1, y = 60}, speed = 20, frame_blend = 0.3, loop = true}, stand = {range = {x = 1, y = 60}, speed = 20, frame_blend = 0.3, loop = true},
fly = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true}, fly = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
glide = {range = {x = 101, y = 119}, speed = 20, frame_blend = 0.2, loop = true}, glide = {range = {x = 101, y = 119}, speed = 20, frame_blend = 0.2, loop = true},
fly_punch = {range = {x = 131, y = 149}, speed = 20, frame_blend = 0.1, loop = false}, fly_punch = {range = {x = 131, y = 149}, speed = 20, frame_blend = 0.1, loop = false},
eat = {range = {x = 161, y = 179}, speed = 20, frame_blend = 0.1, loop = false} eat = {range = {x = 161, y = 179}, speed = 20, frame_blend = 0.1, loop = false}
}, },
-- Misc follow = {"animalia:rat_raw"},
makes_footstep_sound = true, drops = {
{name = "animalia:feather", min = 1, max = 2, chance = 1}
},
-- Animalia Props
flee_puncher = true, -- TODO
catch_with_net = true, catch_with_net = true,
catch_with_lasso = false, catch_with_lasso = false,
--sounds = {}, roost_action = animalia.action_roost,
follow = {"animalia:rat_raw"},
-- Function -- Functions
on_eat_drop = function(self) on_eat_drop = function(self)
animalia.protect_from_despawn(self) animalia.protect_from_despawn(self)
get_home_pos(self) get_home_pos(self)
end, end,
is_home = function(pos, home_pos) is_home = function(pos, home_pos)
if abs(pos.x - home_pos.x) < 0.5 if abs(pos.x - home_pos.x) < 0.5
and abs(pos.z - home_pos.z) < 0.5 then and abs(pos.z - home_pos.z) < 0.5 then
@ -97,11 +91,13 @@ creatura.register_mob("animalia:owl", {
end end
return false return false
end, end,
wander_action = creatura.action_move, wander_action = creatura.action_move,
utility_stack = { utility_stack = {
{ {
utility = "animalia:aerial_wander", utility = "animalia:aerial_wander",
step_delay = 0.25, --step_delay = 0.25,
get_score = function(self) get_score = function(self)
if not self.is_landed if not self.is_landed
or self.in_liquid then or self.in_liquid then
@ -126,7 +122,7 @@ creatura.register_mob("animalia:owl", {
local home = animalia.is_day and self.home_position local home = animalia.is_day and self.home_position
if home if home
and vec_dist(pos, home) < 8 then and vec_dist(pos, home) < 8 then
return 0.6, {self} return 0.2, {self}
end end
return 0 return 0
end end
@ -141,15 +137,19 @@ creatura.register_mob("animalia:owl", {
end end
local food_item = animalia.get_dropped_food(self, "animalia:rat_raw") local food_item = animalia.get_dropped_food(self, "animalia:rat_raw")
if food_item then if food_item then
return 0.7, {self, food_item} return 0.3, {self, food_item}
end end
return 0 return 0
end end
}, },
{ {
utility = "animalia:glide_attack_target", utility = "animalia:raptor_hunt",
get_score = function(self) get_score = function(self)
local target = self._target or creatura.get_nearby_object(self, {"animalia:rat", "animalia:bird"}) if math.random(12) > 1
and (self:get_utility() or "") ~= "animalia:raptor_hunt" then
return 0
end
local target = self._target or creatura.get_nearby_object(self, {"animalia:rat", "animalia:song_bird"})
local tgt_pos = target and target:get_pos() local tgt_pos = target and target:get_pos()
if tgt_pos then if tgt_pos then
return 0.4, {self, target} return 0.4, {self, target}
@ -158,6 +158,7 @@ creatura.register_mob("animalia:owl", {
end end
}, },
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
@ -174,6 +175,7 @@ creatura.register_mob("animalia:owl", {
get_home_pos(self) get_home_pos(self)
end end
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
@ -186,11 +188,13 @@ creatura.register_mob("animalia:owl", {
self.speed = 1 self.speed = 1
end end
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
deactivate_func = function(self) deactivate_func = function(self)
if self:get_utility() if self:get_utility()
and self:get_utility() == "animalia:fly_to_roost" then and self:get_utility() == "animalia:fly_to_roost" then
@ -203,6 +207,7 @@ creatura.register_mob("animalia:owl", {
end end
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, false) then if animalia.feed(self, clicker, false, false) then
return return
@ -211,7 +216,11 @@ creatura.register_mob("animalia:owl", {
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:owl", "412918", "735b46") creatura.register_spawn_item("animalia:owl", {
col1 = "412918",
col2 = "735b46"
})

View file

@ -2,47 +2,10 @@
-- Pig -- -- Pig --
--------- ---------
local follows = {}
minetest.register_on_mods_loaded(function()
for name 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)
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)
creatura.register_mob("animalia:pig", { creatura.register_mob("animalia:pig", {
-- Stats -- Engine Props
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}, visual_size = {x = 10, y = 10},
mesh = "animalia_pig.b3d",
female_textures = { female_textures = {
"animalia_pig_1.png", "animalia_pig_1.png",
"animalia_pig_2.png", "animalia_pig_2.png",
@ -58,21 +21,18 @@ creatura.register_mob("animalia:pig", {
"animalia_pig_2.png", "animalia_pig_2.png",
"animalia_pig_3.png" "animalia_pig_3.png"
}, },
animations = {
stand = {range = {x = 30, y = 50}, speed = 10, 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},
},
-- Misc
makes_footstep_sound = true, makes_footstep_sound = true,
consumable_nodes = destroyable_crops,
birth_count = 2, -- Creatura Props
flee_puncher = true, max_health = 20,
catch_with_net = true, damage = 2,
catch_with_lasso = true, speed = 3,
tracking_range = 12,
despawn_after = 500,
stepheight = 1.1,
sounds = { sounds = {
random = { random = {
name = "animalia_pig_random", name = "animalia_pig",
gain = 1.0, gain = 1.0,
distance = 8 distance = 8
}, },
@ -87,11 +47,33 @@ creatura.register_mob("animalia:pig", {
distance = 8 distance = 8
} }
}, },
hitbox = {
width = 0.35,
height = 0.7
},
animations = {
stand = {range = {x = 1, y = 60}, speed = 20, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 100, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
},
follow = animalia.food_crops,
drops = { drops = {
{name = "animalia:porkchop_raw", min = 1, max = 3, chance = 1} {name = "animalia:porkchop_raw", min = 1, max = 3, chance = 1}
}, },
follow = follows,
-- Function -- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
birth_count = 2,
head_data = {
offset = {x = 0, y = 0.7, z = 0},
pitch_correction = 0,
pivot_h = 0.5,
pivot_v = 0.3
},
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander", utility = "animalia:wander",
@ -101,11 +83,11 @@ creatura.register_mob("animalia:pig", {
end end
}, },
{ {
utility = "animalia:eat_from_turf", utility = "animalia:walk_to_pos_and_interact",
step_delay = 0.25,
get_score = function(self) get_score = function(self)
if math.random(25) < 2 then if math.random(6) < 2
return 0.2, {self} or self:get_utility() == "animalia:walk_to_pos_and_interact" then
return 0.2, {self, animalia.find_crop, animalia.eat_crop}
end end
return 0 return 0
end end
@ -134,21 +116,22 @@ creatura.register_mob("animalia:pig", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.head_tracking(self)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
animalia.random_sound(self) animalia.random_sound(self)
end, end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then death_func = animalia.death_func,
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
@ -157,7 +140,11 @@ creatura.register_mob("animalia:pig", {
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:pig", "e0b1a7" ,"cc9485") creatura.register_spawn_item("animalia:pig", {
col1 = "e0b1a7",
col2 = "cc9485"
})

View file

@ -2,46 +2,85 @@
-- Mice -- -- Mice --
---------- ----------
local vec_add, vec_sub = vector.add, vector.subtract
local function find_chest(self)
local pos = self.object:get_pos()
if not pos then return end
local nodes = minetest.find_nodes_with_meta(vec_sub(pos, 6), vec_add(pos, 6)) or {}
local pos2
for _, node_pos in ipairs(nodes) do
local meta = minetest.get_meta(node_pos)
if meta:get_string("owner") == "" then
local inv = minetest.get_inventory({type = "node", pos = node_pos})
if inv
and inv:get_list("main") then
pos2 = node_pos
end
end
end
return pos2
end
local function take_food_from_chest(self, pos)
local inv = minetest.get_inventory({type = "node", pos = pos})
if inv
and inv:get_list("main") then
for i, stack in ipairs(inv:get_list("main")) do
local item_name = stack:get_name()
local def = minetest.registered_items[item_name]
for group in pairs(def.groups) do
if group:match("food_") then
stack:take_item()
inv:set_stack("main", i, stack)
animalia.add_food_particle(self, item_name)
return true
end
end
end
end
end
creatura.register_mob("animalia:rat", { creatura.register_mob("animalia:rat", {
-- Stats -- Engine Props
max_health = 5,
armor_groups = {fleshy = 100},
damage = 0,
speed = 3,
tracking_range = 12,
despawn_after = 2500,
-- Entity Physics
stepheight = 1.1,
max_fall = 0,
turn_rate = 12,
bouyancy_multiplier = 0.5,
-- Visuals
mesh = "animalia_rat.b3d",
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = "animalia_rat.b3d",
textures = { textures = {
"animalia_rat_1.png", "animalia_rat_1.png",
"animalia_rat_2.png", "animalia_rat_2.png",
"animalia_rat_3.png" "animalia_rat_3.png"
}, },
-- Creatura Props
max_health = 5,
damage = 0,
speed = 1,
tracking_range = 8,
despawn_after = 200,
stepheight = 1.1,
--sound = {},
hitbox = {
width = 0.15,
height = 0.3
},
animations = { animations = {
stand = {range = {x = 1, y = 39}, speed = 20, frame_blend = 0.3, loop = true}, stand = {range = {x = 1, y = 39}, speed = 20, frame_blend = 0.3, loop = true},
walk = {range = {x = 51, y = 69}, speed = 20, frame_blend = 0.3, loop = true}, walk = {range = {x = 51, y = 69}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 81, y = 99}, speed = 45, frame_blend = 0.3, loop = true}, run = {range = {x = 81, y = 99}, speed = 45, frame_blend = 0.3, loop = true},
eat = {range = {x = 111, y = 119}, speed = 20, frame_blend = 0.1, loop = false} eat = {range = {x = 111, y = 119}, speed = 20, frame_blend = 0.1, loop = false}
}, },
-- Misc
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
makes_footstep_sound = false,
drops = { drops = {
{name = "animalia:rat_raw", min = 1, max = 1, chance = 1} {name = "animalia:rat_raw", min = 1, max = 1, chance = 1}
}, },
-- Function
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander", utility = "animalia:wander",
@ -61,21 +100,17 @@ creatura.register_mob("animalia:rat", {
end end
}, },
{ {
utility = "animalia:eat_crop", utility = "animalia:walk_to_pos_and_interact",
get_score = function(self) get_score = function(self)
-- Eat Crops
if math.random(6) < 2 if math.random(6) < 2
or self:get_utility() == "animalia:eat_crop" then or self:get_utility() == "animalia:walk_to_pos_and_interact" then
return 0.2, {self} return 0.2, {self, animalia.find_crop, animalia.eat_crop, "eat"}
end end
return 0 -- Steal From Chest
end
},
{
utility = "animalia:steal_from_chest",
get_score = function(self)
if math.random(12) < 2 if math.random(12) < 2
or self:get_utility() == "animalia:steal_from_chest" then or self:get_utility() == "animalia:walk_to_pos_and_interact" then
return 0.2, {self} return 0.3, {self, find_chest, take_food_from_chest, "eat"}
end end
return 0 return 0
end end
@ -95,26 +130,33 @@ creatura.register_mob("animalia:rat", {
end end
} }
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:rat", "605a55", "ff936f") creatura.register_spawn_item("animalia:rat", {
col1 = "605a55",
col2 = "ff936f"
})

View file

@ -2,56 +2,46 @@
-- Reindeer -- -- Reindeer --
-------------- --------------
local follows = {}
minetest.register_on_mods_loaded(function()
for name 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 random = math.random
creatura.register_mob("animalia:reindeer", { creatura.register_mob("animalia:reindeer", {
-- Stats -- Engine Props
max_health = 20, visual_size = {x = 10, y = 10},
armor_groups = {fleshy = 125}, mesh = "animalia_reindeer.b3d",
textures = {"animalia_reindeer.png"},
child_textures = {"animalia_reindeer_calf.png"},
makes_footstep_sound = true,
-- Creatura Props
max_health = 15,
damage = 0, damage = 0,
speed = 3, speed = 3,
boid_seperation = 1, tracking_range = 12,
tracking_range = 16, max_boids = 4,
despawn_after = 1500, despawn_after = 500,
-- Entity Physics
stepheight = 1.1, stepheight = 1.1,
turn_rate = 4, --sound = {},
-- Visuals
mesh = "animalia_reindeer.b3d",
hitbox = { hitbox = {
width = 0.45, width = 0.45,
height = 0.9 height = 0.9
}, },
visual_size = {x = 10, y = 10},
textures = {"animalia_reindeer.png"},
child_textures = {"animalia_reindeer_calf.png"},
animations = { animations = {
stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true}, stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true}, walk = {range = {x = 70, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true}, run = {range = {x = 100, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
eat = {range = {x = 130, y = 150}, speed = 20, frame_blend = 0.3, loop = false}
}, },
-- Misc follow = animalia.food_wheat,
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
drops = { drops = {
{name = "animalia:venison_raw", min = 1, max = 3, chance = 1}, {name = "animalia:venison_raw", min = 1, max = 3, chance = 1},
{name = "animalia:leather", min = 1, max = 3, chance = 2} {name = "animalia:leather", min = 1, max = 3, chance = 2}
}, },
follow = follows,
-- Animalia Props
group_wander = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
consumable_nodes = { consumable_nodes = {
{ {
name = "default:dirt_with_grass", name = "default:dirt_with_grass",
@ -68,12 +58,11 @@ creatura.register_mob("animalia:reindeer", {
pivot_h = 1, pivot_h = 1,
pivot_v = 1 pivot_v = 1
}, },
move_chance = 2,
idle_time = 1, -- Functions
-- Function
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_group", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
@ -113,21 +102,21 @@ creatura.register_mob("animalia:reindeer", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
end, end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then death_func = animalia.death_func,
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
@ -136,7 +125,11 @@ creatura.register_mob("animalia:reindeer", {
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:reindeer", "413022" ,"d5c0a3") creatura.register_spawn_item("animalia:reindeer", {
col1 = "413022",
col2 = "d5c0a3"
})

View file

@ -4,80 +4,48 @@
local random = math.random local random = math.random
local follows = {}
minetest.register_on_mods_loaded(function()
for name 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:white"
if not minetest.get_modpath("wool") then
wool_block = nil
end
local creative = minetest.settings:get_bool("creative_mode")
local palette = { local palette = {
{"black", "Black", "#000000b0"}, black = {"Black", "#000000b0"},
{"blue", "Blue", "#015dbb70"}, blue = {"Blue", "#015dbb70"},
{"brown", "Brown", "#663300a0"}, brown = {"Brown", "#663300a0"},
{"cyan", "Cyan", "#01ffd870"}, cyan = {"Cyan", "#01ffd870"},
{"dark_green", "Dark Green", "#005b0770"}, dark_green = {"Dark Green", "#005b0770"},
{"dark_grey", "Dark Grey", "#303030b0"}, dark_grey = {"Dark Grey", "#303030b0"},
{"green", "Green", "#61ff0170"}, green = {"Green", "#61ff0170"},
{"grey", "Grey", "#5b5b5bb0"}, grey = {"Grey", "#5b5b5bb0"},
{"magenta", "Magenta", "#ff05bb70"}, magenta = {"Magenta", "#ff05bb70"},
{"orange", "Orange", "#ff840170"}, orange = {"Orange", "#ff840170"},
{"pink", "Pink", "#ff65b570"}, pink = {"Pink", "#ff65b570"},
{"red", "Red", "#ff0000a0"}, red = {"Red", "#ff0000a0"},
{"violet", "Violet", "#2000c970"}, violet = {"Violet", "#2000c970"},
{"white", "White", "#ababab00"}, white = {"White", "#ababab00"},
{"yellow", "Yellow", "#e3ff0070"}, yellow = {"Yellow", "#e3ff0070"},
} }
creatura.register_mob("animalia:sheep", { creatura.register_mob("animalia:sheep", {
-- Stats -- Engine Props
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}, visual_size = {x = 10, y = 10},
mesh = "animalia_sheep.b3d",
textures = { textures = {
"animalia_sheep.png^animalia_sheep_wool.png" "animalia_sheep.png^animalia_sheep_wool.png"
}, },
child_textures = { child_textures = {
"animalia_sheep.png" "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},
},
-- Misc
makes_footstep_sound = true, makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true, -- Creatura Props
catch_with_lasso = true, max_health = 15,
armor_groups = {fleshy = 100},
damage = 0,
speed = 3,
tracking_range = 12,
max_boids = 4,
despawn_after = 500,
stepheight = 1.1,
sounds = { sounds = {
random = { random = {
name = "animalia_sheep_idle", name = "animalia_sheep",
gain = 1.0, gain = 1.0,
distance = 8 distance = 8
}, },
@ -92,11 +60,27 @@ creatura.register_mob("animalia:sheep", {
distance = 8 distance = 8
} }
}, },
hitbox = {
width = 0.4,
height = 0.8
},
animations = {
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 100, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
eat = {range = {x = 130, y = 150}, speed = 20, frame_blend = 0.3, loop = false}
},
follow = animalia.food_wheat,
drops = { drops = {
{name = "animalia:mutton_raw", min = 1, max = 3, chance = 1}, {name = "animalia:mutton_raw", min = 1, max = 3, chance = 1},
{name = wool_block, min = 1, max = 3, chance = 2} minetest.get_modpath("wool") and {name = "wool:white", min = 1, max = 3, chance = 2} or nil
}, },
follow = follows,
-- Animalia Props
group_wander = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
consumable_nodes = { consumable_nodes = {
["default:dirt_with_grass"] = "default:dirt", ["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt" ["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
@ -107,10 +91,11 @@ creatura.register_mob("animalia:sheep", {
pivot_h = 0.75, pivot_h = 0.75,
pivot_v = 0.85 pivot_v = 0.85
}, },
-- Function
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_group", utility = "animalia:wander",
step_delay = 0.25, step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
@ -150,38 +135,34 @@ creatura.register_mob("animalia:sheep", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.collected = self:recall("collected") or false self.collected = self:recall("collected") or false
self.dye_color = self:recall("dye_color") or "white" 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.collected then
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[colorize:" .. self.dye_hex .. ")"},
})
end
if self.collected then if self.collected then
self.object:set_properties({ self.object:set_properties({
textures = {"animalia_sheep.png"}, textures = {"animalia_sheep.png"},
}) })
elseif self.dye_color ~= "white" then
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[multiply:" .. palette[self.dye_color][2] .. ")"},
})
end end
self.attention_span = 8
self._path = {}
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
animalia.random_sound(self) animalia.random_sound(self)
end, end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then death_func = animalia.death_func,
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
@ -189,61 +170,61 @@ creatura.register_mob("animalia:sheep", {
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
if self.collected
or self.growth_scale < 1 then
return
end
local tool = clicker:get_wielded_item() local tool = clicker:get_wielded_item()
local tool_name = tool:get_name() local tool_name = tool:get_name()
if tool_name == "animalia:shears" local creative = minetest.is_creative_enabled(clicker)
and not self.collected
and self.growth_scale > 0.9 then if tool_name == "animalia:shears" then
if not minetest.get_modpath("wool") then if not minetest.get_modpath("wool") then
return return
end end
minetest.add_item( minetest.add_item(
self.object:get_pos(), self.object:get_pos(),
ItemStack( "wool:" .. self.dye_color .. " " .. math.random(1, 3) ) ItemStack("wool:" .. self.dye_color .. " " .. random(1, 3))
) )
self.collected = self:memorize("collected", true) self.collected = self:memorize("collected", true)
self.dye_color = self:memorize("dye_color", "white") self.dye_color = self:memorize("dye_color", "white")
self.dye_hex = self:memorize("dye_hex", "#abababc000")
tool:add_wear(650) -- 100 uses
clicker:set_wielded_item(tool)
self.object:set_properties({ self.object:set_properties({
textures = {"animalia_sheep.png"}, textures = {"animalia_sheep.png"},
}) })
if not creative then
tool:add_wear(650)
clicker:set_wielded_item(tool)
end
end end
for _, color in ipairs(palette) do
if tool_name:find("dye:")
and not self.collected
and self.growth_scale > 0.9 then
local dye = tool_name:split(":")[2]
if color[1] == dye then
self.dye_color = self:memorize("dye_color", color[1]) if tool_name:match("^dye:") then
self.dye_hex = self:memorize("dye_hex", color[3]) local dye_color = tool_name:split(":")[2]
if palette[dye_color] then
self.drops = { self.dye_color = self:memorize("dye_color", dye_color)
{name = "animalia:mutton_raw", chance = 1, min = 1, max = 4}, self.drops = {
{name = "wool:"..self.dye_color, chance = 2, min = 1, max = 2}, {name = "animalia:mutton_raw", chance = 1, min = 1, max = 4},
} {name = "wool:" .. dye_color, chance = 2, min = 1, max = 2},
}
self.object:set_properties({ self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[colorize:" .. color[3] .. ")"}, textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[multiply:" .. palette[dye_color][2] .. ")"},
}) })
if not creative then
if not creative then tool:take_item()
tool:take_item() clicker:set_wielded_item(tool)
clicker:set_wielded_item(tool)
end
break
end end
end end
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b") creatura.register_spawn_item("animalia:sheep", {
col1 = "f4e6cf",
col2 = "e1ca9b"
})

167
mobs/song_bird.lua Normal file
View file

@ -0,0 +1,167 @@
---------------
-- Song Bird --
---------------
local random = math.random
creatura.register_mob("animalia:song_bird", {
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_bird.b3d",
textures = {
"animalia_cardinal.png",
"animalia_bluebird.png",
"animalia_goldfinch.png"
},
-- Creatura Props
max_health = 2,
speed = 4,
tracking_range = 8,
max_boids = 6,
boid_seperation = 0.3,
despawn_after = 200,
max_fall = 0,
stepheight = 1.1,
sounds = {
cardinal = {
name = "animalia_cardinal",
gain = 0.5,
distance = 63
},
eastern_blue = {
name = "animalia_bluebird",
gain = 0.5,
distance = 63
},
goldfinch = {
name = "animalia_goldfinch",
gain = 0.5,
distance = 63
},
},
hitbox = {
width = 0.2,
height = 0.4
},
animations = {
stand = {range = {x = 1, y = 100}, speed = 30, frame_blend = 0.3, loop = true},
walk = {range = {x = 110, y = 130}, speed = 40, frame_blend = 0.3, loop = true},
fly = {range = {x = 140, y = 160}, speed = 40, frame_blend = 0.3, loop = true}
},
--follow = {},
drops = {
{name = "animalia:feather", min = 1, max = 1, chance = 2}
},
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
wander_action = animalia.action_boid_move,
--roost_action = animalia.action_roost,
-- Functions
utility_stack = {
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
end
},
{
utility = "animalia:aerial_wander",
get_score = function(self)
if self.is_landed then
local player = creatura.get_nearby_player(self)
if player then
self.is_landed = self:memorize("is_landed", false)
end
end
if not self.is_landed
or self.in_liquid then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:fly_to_land",
get_score = function(self)
if self.is_landed
and not self.touching_ground
and not self.in_liquid
and creatura.sensor_floor(self, 3, true) > 2 then
return 0.3, {self}
end
return 0
end
}
},
activate_func = function(self)
if animalia.despawn_inactive_mob(self) then return end
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.is_landed = (random(2) < 2 and true) or false
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
--animalia.update_lasso_effects(self)
animalia.rotate_to_pitch(self)
if self:timer(random(6, 12)) then
if animalia.is_day 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
end
if not self.is_landed
or not self.touching_ground then
self.speed = 4
else
self.speed = 3
end
end,
death_func = animalia.death_func,
on_rightclick = function(self, clicker)
--[[if animalia.feed(self, clicker, false, false) then
return
end]]
if animalia.set_nametag(self, clicker) then
return
end
end,
on_punch = animalia.punch
})
creatura.register_spawn_item("animalia:song_bird", {
col1 = "ae2f2f",
col2 = "f3ac1c"
})
minetest.register_entity("animalia:bird", {
static_save = false,
on_activate = function(self)
self.object:remove()
end
})
minetest.register_abm({
label = "animalia:nest_cleanup",
nodenames = "animalia:nest_song_bird",
interval = 900,
action = function(pos)
minetest.remove_node(pos)
end
})

View file

@ -3,30 +3,12 @@
---------- ----------
creatura.register_mob("animalia:tropical_fish", { creatura.register_mob("animalia:tropical_fish", {
-- Stats -- Engine Props
max_health = 5, visual_size = {x = 10, y = 10},
max_breath = 0,
armor_groups = {fleshy = 150},
damage = 0,
speed = 2,
tracking_range = 6,
despawn_after = 2500,
-- Entity Physics
stepheight = 0.1,
max_fall = 0,
turn_rate = 8,
boid_seperation = 0.3,
bouyancy_multiplier = 0,
-- Visuals
meshes = { meshes = {
"animalia_clownfish.b3d", "animalia_clownfish.b3d",
"animalia_angelfish.b3d" "animalia_angelfish.b3d"
}, },
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 10, y = 10},
mesh_textures = { mesh_textures = {
{ {
"animalia_clownfish.png", "animalia_clownfish.png",
@ -36,15 +18,35 @@ creatura.register_mob("animalia:tropical_fish", {
"animalia_angelfish.png" "animalia_angelfish.png"
} }
}, },
-- Creatura Props
max_health = 5,
armor_groups = {fleshy = 150},
damage = 0,
max_breath = 0,
speed = 2,
tracking_range = 6,
max_boids = 6,
boid_seperation = 0.3,
despawn_after = 200,
max_fall = 3,
stepheight = 1.1,
hitbox = {
width = 0.15,
height = 0.3
},
animations = { animations = {
swim = {range = {x = 1, y = 20}, speed = 20, frame_blend = 0.3, loop = true}, 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}, flop = {range = {x = 30, y = 40}, speed = 20, frame_blend = 0.3, loop = true},
}, },
-- Misc bouyancy_multiplier = 0,
-- Animalia Props
flee_puncher = false,
catch_with_net = true, catch_with_net = true,
catch_with_lasso = false, catch_with_lasso = false,
makes_footstep_sound = false,
-- Function -- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:aquatic_wander_school", utility = "animalia:aquatic_wander_school",
@ -65,29 +67,37 @@ creatura.register_mob("animalia:tropical_fish", {
end end
}, },
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.set_nametag(self, clicker) then if animalia.set_nametag(self, clicker) then
return return
end end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:tropical_fish", "e28821", "f6e5d2") creatura.register_spawn_item("animalia:tropical_fish", {
col1 = "e28821",
col2 = "f6e5d2"
})
animalia.alias_mob("animalia:clownfish", "animalia:tropical_fish") animalia.alias_mob("animalia:clownfish", "animalia:tropical_fish")
animalia.alias_mob("animalia:blue_tang", "animalia:tropical_fish") animalia.alias_mob("animalia:blue_tang", "animalia:tropical_fish")

View file

@ -2,71 +2,63 @@
-- Turkey -- -- Turkey --
------------ ------------
local follows = {}
minetest.register_on_mods_loaded(function()
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
end
end
end)
creatura.register_mob("animalia:turkey", { creatura.register_mob("animalia:turkey", {
-- Stats -- Engine Props
max_health = 10, visual_size = {x = 10, y = 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", mesh = "animalia_turkey.b3d",
female_textures = {"animalia_turkey_hen.png"},
male_textures = {"animalia_turkey_tom.png"},
child_textures = {"animalia_turkey_chick.png"},
makes_footstep_sound = true,
-- Creatura Props
max_health = 8,
armor_groups = {fleshy = 100},
damage = 0,
speed = 2,
tracking_range = 8,
max_boids = 3,
despawn_after = 500,
max_fall = 0,
stepheight = 1.1,
sounds = {
random = {
name = "animalia_turkey",
gain = 0.5,
distance = 8
},
hurt = {
name = "animalia_turkey_hurt",
gain = 0.5,
distance = 8
},
death = {
name = "animalia_turkey_death",
gain = 0.5,
distance = 8
}
},
hitbox = { hitbox = {
width = 0.3, width = 0.3,
height = 0.6 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"},
animations = { animations = {
stand = {range = {x = 0, y = 0}, speed = 1, frame_blend = 0.3, loop = true}, 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}, walk = {range = {x = 10, y = 30}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 40, y = 60}, speed = 45, frame_blend = 0.3, loop = true}, 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}, fall = {range = {x = 70, y = 90}, speed = 30, frame_blend = 0.3, loop = true},
}, },
-- Misc follow = animalia.food_seeds,
makes_footstep_sound = true, drops = {
{name = "animalia:poultry_raw", min = 1, max = 4, chance = 1},
{name = "animalia:feather", min = 1, max = 3, chance = 2}
},
-- Animalia Props
group_wander = true,
flee_puncher = true, flee_puncher = true,
catch_with_net = true, catch_with_net = true,
catch_with_lasso = true, catch_with_lasso = true,
sounds = {
random = {
name = "animalia_turkey_idle",
gain = 1.0,
distance = 8
},
hurt = {
name = "animalia_turkey_hurt",
gain = 1.0,
distance = 8
},
death = {
name = "animalia_turkey_death",
gain = 1.0,
distance = 8
}
},
drops = {
{name = "animalia:poultry_raw", min = 2, max = 4, chance = 1},
{name = "animalia:feather", min = 2, max = 4, chance = 2}
},
follow = follows,
head_data = { head_data = {
offset = {x = 0, y = 0.15, z = 0}, offset = {x = 0, y = 0.15, z = 0},
pitch_correction = 45, pitch_correction = 45,
@ -75,38 +67,19 @@ creatura.register_mob("animalia:turkey", {
}, },
move_chance = 2, move_chance = 2,
idle_time = 1, idle_time = 1,
-- Function
add_child = function(self) -- Functions
local pos = self.object:get_pos()
if not pos then return end
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",
})
local object = minetest.add_entity(pos, self.name)
local ent = object:get_luaentity()
ent.growth_scale = 0.7
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
wander_action = creatura.action_move,
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_group", utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self) get_score = function(self)
return 0.1, {self} return 0.1, {self}
end end
}, },
{ {
utility = "animalia:swim_to_Land", utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self) get_score = function(self)
if self.in_liquid then if self.in_liquid then
return 0.5, {self} return 0.5, {self}
@ -117,6 +90,7 @@ creatura.register_mob("animalia:turkey", {
animalia.global_utils.basic_follow, animalia.global_utils.basic_follow,
{ {
utility = "animalia:breed", utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self) get_score = function(self)
if self.breeding if self.breeding
and animalia.get_nearby_mate(self, self.name) then and animalia.get_nearby_mate(self, self.name) then
@ -127,10 +101,23 @@ creatura.register_mob("animalia:turkey", {
}, },
animalia.global_utils.basic_flee animalia.global_utils.basic_flee
}, },
add_child = function(self)
local pos = self.object:get_pos()
if not pos then return end
animalia.particle_spawner(pos, "animalia_egg_fragment.png", "splash", pos, pos)
local object = minetest.add_entity(pos, self.name)
local ent = object:get_luaentity()
ent.growth_scale = 0.7
animalia.initialize_api(ent)
animalia.protect_from_despawn(ent)
end,
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75) animalia.head_tracking(self, 0.75, 0.75)
@ -147,20 +134,24 @@ creatura.register_mob("animalia:turkey", {
animalia.random_drop_item(self, "animalia:turkey_egg", 10) animalia.random_drop_item(self, "animalia:turkey_egg", 10)
end end
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then if animalia.feed(self, clicker, false, true) then
return return
end end
if animalia.set_nametag(self, clicker) then animalia.set_nametag(self, clicker)
return
end
end, end,
on_punch = animalia.punch on_punch = animalia.punch
}) })
creatura.register_spawn_egg("animalia:turkey", "352b22", "2f2721") creatura.register_spawn_item("animalia:turkey", {
col1 = "352b22",
col2 = "2f2721"
})

View file

@ -44,48 +44,51 @@ local function is_value_in_table(tbl, val)
end end
creatura.register_mob("animalia:wolf", { creatura.register_mob("animalia:wolf", {
-- Stats -- Engine Props
max_health = 25,
armor_groups = {fleshy = 100},
damage = 4,
speed = 5,
tracking_range = 24,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
max_fall = 3,
-- Visuals
mesh = "animalia_wolf.b3d",
hitbox = {
width = 0.35,
height = 0.7
},
visual_size = {x = 10, y = 10}, visual_size = {x = 10, y = 10},
mesh = "animalia_wolf.b3d",
textures = { textures = {
"animalia_wolf_1.png", "animalia_wolf_1.png",
"animalia_wolf_2.png", "animalia_wolf_2.png",
"animalia_wolf_3.png", "animalia_wolf_3.png",
"animalia_wolf_4.png" "animalia_wolf_4.png"
}, },
animations = {
stand = {range = {x = 1, y = 39}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 41, y = 59}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 41, y = 59}, speed = 45, frame_blend = 0.3, loop = true},
sit = {range = {x = 61, y = 79}, speed = 20, frame_blend = 0.3, loop = true},
},
-- Misc
makes_footstep_sound = true, makes_footstep_sound = true,
-- Creatura Props
max_health = 20,
damage = 4,
speed = 4,
tracking_range = 24,
despawn_after = 500,
stepheight = 1.1,
sound = {},
hitbox = {
width = 0.35,
height = 0.7
},
animations = {
stand = {range = {x = 1, y = 60}, speed = 20, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 100, y = 119}, speed = 40, frame_blend = 0.3, loop = true},
sit = {range = {x = 130, y = 139}, speed = 10, frame_blend = 0.3, loop = true},
},
follow = follow,
-- Animalia Props
assist_owner = true,
flee_puncher = false,
catch_with_net = true, catch_with_net = true,
catch_with_lasso = true, catch_with_lasso = true,
assist_owner = true, consumable_nodes = {},
follow = follow,
head_data = { head_data = {
offset = {x = 0, y = 0.33, z = 0}, offset = {x = 0, y = 0.22, z = 0},
pitch_correction = -67, pitch_correction = -35,
pivot_h = 0.65, pivot_h = 0.45,
pivot_v = 0.65 pivot_v = 0.45
}, },
-- Function
-- Functions
utility_stack = { utility_stack = {
{ {
utility = "animalia:wander_skittish", utility = "animalia:wander_skittish",
@ -156,6 +159,7 @@ creatura.register_mob("animalia:wolf", {
end end
} }
}, },
activate_func = function(self) activate_func = function(self)
animalia.initialize_api(self) animalia.initialize_api(self)
animalia.initialize_lasso(self) animalia.initialize_lasso(self)
@ -169,17 +173,36 @@ creatura.register_mob("animalia:wolf", {
end end
end end
end, end,
step_func = function(self) step_func = function(self)
animalia.step_timers(self) animalia.step_timers(self)
animalia.head_tracking(self, 0.5, 0.75) animalia.head_tracking(self)
animalia.do_growth(self, 60) animalia.do_growth(self, 60)
animalia.update_lasso_effects(self) animalia.update_lasso_effects(self)
end, end,
death_func = function(self) death_func = function(self)
if self:get_utility() ~= "animalia:die" then if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self) self:initiate_utility("animalia:die", self)
end end
end, end,
deactivate_func = function(self)
if self.owner then
for i, object in ipairs(animalia.pets[self.owner] or {}) do
if object == self.object then
animalia.pets[self.owner][i] = nil
end
end
end
if self.enemies
and self.enemies[1]
and self.memorize then
self.enemies[1] = nil
self.enemies = self:memorize("enemies", self.enemies)
end
end,
on_rightclick = function(self, clicker) on_rightclick = function(self, clicker)
if not clicker:is_player() then return end if not clicker:is_player() then return end
local name = clicker:get_player_name() local name = clicker:get_player_name()
@ -213,6 +236,7 @@ creatura.register_mob("animalia:wolf", {
self:memorize("order", self.order) self:memorize("order", self.order)
end end
end, end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage) 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) creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
local name = puncher:is_player() and puncher:get_player_name() local name = puncher:is_player() and puncher:get_player_name()
@ -234,21 +258,9 @@ creatura.register_mob("animalia:wolf", {
end end
self._target = puncher self._target = puncher
end, end,
deactivate_func = function(self)
if self.owner then
for i, object in ipairs(animalia.pets[self.owner] or {}) do
if object == self.object then
animalia.pets[self.owner][i] = nil
end
end
end
if self.enemies
and self.enemies[1]
and self.memorize then
self.enemies[1] = nil
self.enemies = self:memorize("enemies", self.enemies)
end
end
}) })
creatura.register_spawn_egg("animalia:wolf", "a19678" ,"231b13") creatura.register_spawn_item("animalia:wolf", {
col1 = "a19678",
col2 = "231b13"
})

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB