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 --
---------
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 --
local abs = math.abs
@ -65,12 +53,6 @@ local vec_len = vector.length
local dir2yaw = minetest.dir_to_yaw
local yaw2dir = minetest.yaw_to_dir
--------------
-- Settings --
--------------
local creative = minetest.settings:get_bool("creative_mode")
------------
-- Common --
------------
@ -88,8 +70,6 @@ function animalia.correct_name(str)
end
end
local correct_name = animalia.correct_name
---------------------
-- Local Utilities --
---------------------
@ -109,7 +89,7 @@ if minetest.get_modpath("default")
and minetest.get_modpath("player_api") then
animate_player = player_api.set_animation
elseif minetest.get_modpath("mcl_player") then
animate_player = mcl_player.set_animation
animate_player = mcl_player.player_set_animation
end
-----------------------
@ -269,16 +249,8 @@ end
function animalia.particle_spawner(pos, texture, type, min_pos, max_pos)
type = type or "float"
min_pos = min_pos or {
x = pos.x - 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,
}
min_pos = min_pos or vec_sub(pos, 2)
max_pos = max_pos or vec_add(pos, 2)
if type == "float" then
minetest.add_particlespawner({
amount = 16,
@ -312,14 +284,52 @@ function animalia.particle_spawner(pos, texture, type, min_pos, max_pos)
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 --
----------
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()
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
local ent = object:get_luaentity()
if ent
@ -337,6 +347,19 @@ function animalia.protect_from_despawn(self)
self.despawn_after = self:memorize("despawn_after", false)
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)
local plyr_name = clicker and clicker:get_player_name()
if not plyr_name then return end
@ -391,7 +414,12 @@ function animalia.initialize_api(self)
self.texture_no = random(#textures)
end
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
@ -406,6 +434,7 @@ function animalia.step_timers(self)
end
self:memorize("breeding_cooldown", self.breeding_cooldown)
self:memorize("trust_cooldown", self.trust_cooldown)
self:memorize("_last_active", os.time())
end
function animalia.do_growth(self, interval)
@ -422,6 +451,7 @@ function animalia.do_growth(self, interval)
end
self:set_texture(tex_no, self.child_textures)
elseif self.growth_scale == 0.8 then
if self.child_mesh then self:set_mesh() end
if self.male_textures
and self.female_textures then
if #self.child_textures == 1 then
@ -434,6 +464,9 @@ function animalia.do_growth(self, interval)
end
self:set_texture(self.texture_no, self.textures)
end
if self.on_grown then
self:on_grown()
end
end
self:memorize("growth_scale", self.growth_scale)
end
@ -448,6 +481,7 @@ function animalia.random_sound(self)
end
function animalia.add_trust(self, player, amount)
if self.trust_cooldown > 0 then return end
self.trust_cooldown = 60
local plyr_name = player:get_player_name()
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
self.breeding = true
self.breeding_cooldown = 60
animalia.particle_spawner(pos, "heart.png", "float", minp, maxp)
animalia.particle_spawner(pos, "heart.png", "float")
end
end
self._despawn = self:memorize("_despawn", false)
@ -575,6 +609,26 @@ function animalia.punch(self, puncher, ...)
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 --
--------------

File diff suppressed because it is too large Load diff

View file

@ -3,18 +3,9 @@
-----------
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 dir2yaw, dir2rot = minetest.dir_to_yaw, vector.dir_to_rotation
local dir2rot = vector.dir_to_rotation
-- Entities --
@ -29,7 +20,7 @@ minetest.register_entity("animalia:lasso_entity", {
self.object:set_armor_groups({immortal = 1})
end,
_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 pointed_ent = self._point_to and self._point_to:get_luaentity()
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
-- Attachment point of entity
ent._attached = origin
if type(origin) == "string" then
if type(origin) ~= "string" then
--local player = minetest.get_player_by_name(origin)
--object:set_attach(player)
else
--else
object:set_pos(origin)
end
self._lassod_to = origin

View file

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

View file

@ -2,11 +2,20 @@
-- 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 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
@ -43,6 +52,17 @@ creatura.register_abm_spawn("animalia:chicken", {
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", {
chance = common_spawn_chance,
min_height = 0,
@ -76,7 +96,7 @@ creatura.register_abm_spawn("animalia:horse", {
})
creatura.register_abm_spawn("animalia:rat", {
chance = 2000,
chance = pest_spawn_chance,
interval = 60,
min_height = -1,
max_height = 1024,
@ -162,7 +182,7 @@ creatura.register_abm_spawn("animalia:bat", {
nodes = {"group:stone"}
})
creatura.register_abm_spawn("animalia:bird", {
creatura.register_abm_spawn("animalia:song_bird", {
chance = ambient_spawn_chance,
interval = 60,
min_light = 0,
@ -170,25 +190,21 @@ creatura.register_abm_spawn("animalia:bird", {
max_height = 1024,
min_group = 6,
max_group = 12,
spawn_cap = 12,
nodes = {"group:leaves"},
spawn_cap = 6,
nodes = {"group:leaves", "animalia:nest_song_bird"},
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(
{x = pos.x - 12, y = pos.y - 12, z = pos.z - 12},
{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 + 16, y = pos.y + 16, z = pos.z + 16},
"animalia:nest_song_bird"
)
if nests[1] then
self.home_position = self:memorize("home_position", nests[1])
return
end
if nests[1] then return end
local node = minetest.get_node(pos)
if node.name == "air" then
minetest.set_node(pos, {name = "animalia:nest_song_bird"})
self.home_position = self:memorize("home_position", pos)
else
local nodes = minetest.find_nodes_in_area_under_air(
{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
pos = nodes[1]
minetest.set_node({x = pos.x, y = pos.y + 1, z = pos.z}, {name = "animalia:nest_song_bird"})
self.home_position = self:memorize("home_position", {x = pos.x, y = pos.y + 1, z = pos.z})
end
end
end)
creatura.register_abm_spawn("animalia:frog", {
chance = ambient_spawn_chance,
chance = ambient_spawn_chance * 0.75,
interval = 60,
min_light = 0,
min_height = -1,
max_height = 8,
min_group = 2,
max_group = 4,
min_group = 1,
max_group = 2,
neighbors = {"group:water"},
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", {
chance = ambient_spawn_chance,
min_height = -128,

View file

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

View file

@ -31,6 +31,66 @@ end
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/behaviors.lua")
dofile(path.."/api/lasso.lua")
@ -38,7 +98,7 @@ dofile(path.."/craftitems.lua")
animalia.animals = {
"animalia:bat",
"animalia:bird",
"animalia:song_bird",
"animalia:cat",
"animalia:chicken",
"animalia:cow",
@ -80,8 +140,8 @@ minetest.register_on_mods_loaded(function()
old_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
local pos = self.object:get_pos()
if not pos then return end
local name = puncher:is_player() and puncher:get_player_name()
local pets = (name and animalia.pets[name]) or {}
local plyr_name = puncher:is_player() and puncher:get_player_name()
local pets = (plyr_name and animalia.pets[plyr_name]) or {}
for _, obj in ipairs(pets) do
local ent = obj and obj:get_luaentity()
if ent

View file

@ -32,7 +32,6 @@ end
creatura.register_mob("animalia:bat", {
-- Engine Props
visual = "mesh",
visual_size = {x = 10, y = 10},
mesh = "animalia_bat.b3d",
textures = {
@ -41,16 +40,23 @@ creatura.register_mob("animalia:bat", {
"animalia_bat_3.png",
},
makes_footstep_sound = false,
stepheight = 1.1,
-- Creatura Props
max_health = 5,
max_health = 2,
armor_groups = {fleshy = 100},
damage = 0,
speed = 6,
tracking_range = 8,
max_boids = 2,
despawn_after = 500,
speed = 4,
tracking_range = 12,
max_boids = 3,
despawn_after = 200,
max_fall = 0,
sounds = {
random = {
name = "animalia_bat",
gain = 0.5,
distance = 16
}
},
hitbox = {
width = 0.15,
height = 0.3
@ -66,11 +72,14 @@ creatura.register_mob("animalia:bat", {
"butterflies:butterfly_white",
"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,
-- Functions
utility_stack = {
{
utility = "animalia:aerial_wander",
@ -81,7 +90,6 @@ creatura.register_mob("animalia:bat", {
local player = creatura.get_nearby_player(self)
local plyr_pos = player and not player:get_player_control().sneak and player:get_pos()
if plyr_pos then
local trust = self.trust[player:get_player_name() or ""] or 0
local dist = vec_dist(pos, plyr_pos)
self._target = player
self.is_landed = false
@ -116,10 +124,7 @@ creatura.register_mob("animalia:bat", {
end
}
},
-- Animalia Props
catch_with_net = true,
catch_with_lasso = false,
-- Functions
is_home = function(pos, home_pos)
local dist = vec_dist(pos, home_pos)
if dist < 4 then
@ -131,6 +136,7 @@ creatura.register_mob("animalia:bat", {
end
return false
end,
activate_func = function(self)
animalia.initialize_api(self)
self.home_position = self:recall("home_position") or nil
@ -142,6 +148,7 @@ creatura.register_mob("animalia:bat", {
get_home_pos(self)
end
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
@ -184,11 +191,13 @@ creatura.register_mob("animalia:bat", {
end
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, false) then
animalia.add_trust(self, clicker, 1)
@ -198,6 +207,7 @@ creatura.register_mob("animalia:bat", {
return
end
end,
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 vec_dist = vector.distance
local vec_dist, vec_add, vec_sub = vector.distance, vector.add, vector.subtract
local follow = {
"animalia:poultry_raw"
@ -17,24 +17,28 @@ if minetest.registered_items["ethereal:fish_raw"] then
}
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", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_cat.b3d",
textures = {
"animalia_cat_1.png",
"animalia_cat_2.png",
@ -48,22 +52,23 @@ creatura.register_mob("animalia:cat", {
"animalia_cat_ash.png",
"animalia_cat_birch.png",
},
animations = {
stand = {range = {x = 1, y = 39}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 41, y = 59}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 42, y = 59}, speed = 30, frame_blend = 0.3, loop = true},
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},
smack = {range = {x = 101, y = 119}, speed = 40, frame_blend = 0.1, loop = true},
},
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
use_texture_alpha = false,
makes_footstep_sound = false,
backface_culling = true,
glow = 0,
-- Creatura Props
max_health = 10,
damage = 1,
speed = 3,
tracking_range = 16,
max_boids = 0,
despawn_after = 500,
max_fall = 0,
stepheight = 1.1,
sounds = {
random = {
name = "animalia_cat_idle",
name = "animalia_cat",
gain = 0.25,
distance = 8
},
@ -83,32 +88,35 @@ creatura.register_mob("animalia:cat", {
distance = 8
}
},
follow = follow,
head_data = {
offset = {x = 0, y = 0.18, z = 0},
pitch_correction = -20,
pivot_h = 0.65,
pivot_v = 0.65
hitbox = {
width = 0.2,
height = 0.4
},
-- Function
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,
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,
drops = {},
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
head_data = {
offset = {x = 0, y = 0.14, z = 0},
pitch_correction = -25,
pivot_h = 0.4,
pivot_v = 0.4
},
skittish_wander = true,
-- Functions
utility_stack = {
{
utility = "animalia:wander_skittish",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
@ -125,11 +133,11 @@ creatura.register_mob("animalia:cat", {
end
},
{
utility = "animalia:destroy_nearby_vessel",
utility = "animalia:walk_to_pos_and_interact",
step_delay = 0.25,
get_score = function(self)
if random(24) < 2 then
return 0.2, {self}
if random(2) < 2 then
return 0.2, {self, find_glass_vessel, destroy_glass_vessel, nil, 10}
end
return 0
end
@ -217,6 +225,23 @@ creatura.register_mob("animalia:cat", {
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)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
@ -229,38 +254,39 @@ creatura.register_mob("animalia:cat", {
end
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
death_func = animalia.death_func,
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)
local item_name = clicker:get_wielded_item():get_name()
if item_name == "animalia:net" then return end
local trust = self.trust[clicker:get_player_name()] or 0
local pos = self.object:get_pos()
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 self.trust_cooldown <= 0
and trust < 10 then
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
animalia.add_trust(self, clicker, 1)
animalia.particle_spawner(pos, "creatura_particle_green.png", "float")
return
end
if animalia.set_nametag(self, clicker) then
return
end
-- Initiate trust
if not self.trust[clicker:get_player_name()] then
self.trust[clicker:get_player_name()] = 0
self:memorize("trust", self.trust)
end
-- Purr to indicate trust level (louder = more trust)
if clicker:get_player_control().sneak then
if self.interact_sound_cooldown <= 0 then
@ -288,49 +314,35 @@ creatura.register_mob("animalia:cat", {
end
local order = self.order
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:initiate_utility("animalia:follow_player", self, clicker, true)
self:set_utility_score(0.7)
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:initiate_utility("animalia:stay", self)
self:set_utility_score(0.5)
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:set_utility_score(0)
end
self:memorize("order", self.order)
end
end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
self:initiate_utility("animalia:flee_from_player", self, puncher)
self:set_utility_score(1)
if not self.trust[puncher:get_player_name()] then
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
animalia.add_trust(self, puncher, -1)
local pos = self.object:get_pos()
pos = vector.new(pos.x, pos.y + 0.5, pos.z)
local minppos = vector.add(pos, 1)
local maxppos = vector.subtract(pos, 1)
animalia.particle_spawner(pos, "creatura_particle_red.png", "float", minppos, maxppos)
self:memorize("trust", self.trust)
end,
deactivate_func = function(self)
if self.owner 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
animalia.particle_spawner(pos, "creatura_particle_red.png", "float")
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 --
-------------
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", {
-- Stats
max_health = 5,
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
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_chicken.b3d",
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 7, y = 7},
female_textures = {
"animalia_chicken_1.png",
"animalia_chicken_2.png",
@ -43,21 +17,21 @@ creatura.register_mob("animalia:chicken", {
"animalia_rooster_3.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,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
-- Creatura Props
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 = {
random = {
name = "animalia_chicken_idle",
name = "animalia_chicken",
gain = 0.5,
distance = 8
},
@ -72,11 +46,28 @@ creatura.register_mob("animalia:chicken", {
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 = {
{name = "animalia:poultry_raw", min = 1, max = 3, chance = 1},
{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 = {
offset = {x = 0, y = 0.45, z = 0},
pitch_correction = 40,
@ -85,31 +76,11 @@ creatura.register_mob("animalia:chicken", {
},
move_chance = 2,
idle_time = 1,
-- Function
add_child = function(self)
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,
-- Functions
utility_stack = {
{
utility = "animalia:wander_group",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
@ -139,10 +110,23 @@ creatura.register_mob("animalia:chicken", {
},
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)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
@ -159,20 +143,24 @@ creatura.register_mob("animalia:chicken", {
animalia.random_drop_item(self, "animalia:chicken_egg", 10)
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
end
if animalia.set_nametag(self, clicker) then
return
end
animalia.set_nametag(self, clicker)
end,
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 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", {
-- Engine Props
@ -42,17 +30,35 @@ creatura.register_mob("animalia:cow", {
"animalia_cow_4.png",
"animalia_cow_5.png"
},
stepheight = 1.1,
makes_footstep_sound = true,
-- Creatura Props
max_health = 20,
armor_groups = {fleshy = 100},
damage = 0,
speed = 4,
tracking_range = 16,
despawn_after = 1000,
speed = 2,
tracking_range = 10,
max_boids = 0,
despawn_after = 500,
max_fall = 3,
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 = {
width = 0.5,
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},
run = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
},
follow = follows,
follow = animalia.food_wheat,
drops = {
{name = "animalia:beef_raw", min = 1, max = 3, chance = 1},
{name = "animalia:leather", min = 1, max = 3, chance = 2}
},
fancy_collide = false,
bouyancy_multiplier = 1,
hydrodynamics_multiplier = 1,
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
@ -79,12 +84,14 @@ creatura.register_mob("animalia:cow", {
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
},
head_data = {
offset = {x = 0, y = 0.8, z = 0.0},
pitch_correction = -65,
offset = {x = 0, y = 0.5, z = 0.0},
pitch_correction = -40,
pivot_h = 0.75,
pivot_v = 1
},
wander_action = animalia.action_boid_move,
-- Functions
utility_stack = {
{
utility = "animalia:wander",
@ -127,12 +134,13 @@ creatura.register_mob("animalia:cow", {
},
animalia.global_utils.basic_flee
},
-- Functions
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.collected = self:recall("collected") or false
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
@ -140,18 +148,19 @@ creatura.register_mob("animalia:cow", {
animalia.update_lasso_effects(self)
animalia.random_sound(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
end
if animalia.set_nametag(self, clicker) then
if animalia.feed(self, clicker, false, true)
or animalia.set_nametag(self, clicker) then
return
end
local tool = clicker:get_wielded_item()
local name = clicker:get_player_name()
@ -183,7 +192,11 @@ creatura.register_mob("animalia:cow", {
return
end
end,
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", {
-- Stats
max_health = 15,
armor_groups = {fleshy = 100},
damage = 4,
speed = 5,
tracking_range = 24,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
max_fall = 3,
-- Visuals
-- Engine Props
visual_size = {x = 10, y = 10},
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 = {
width = 0.35,
height = 0.7
},
visual_size = {x = 10, y = 10},
textures = {
"animalia_fox_1.png",
height = 0.5
},
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},
},
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
follow = {
"animalia:rat_raw",
"animalia:mutton_raw",
@ -40,19 +76,23 @@ creatura.register_mob("animalia:fox", {
"animalia:porkchop_raw",
"animalia:poultry_raw"
},
-- Animalia Props
skittish_wander = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
head_data = {
offset = {x = 0, y = 0.18, z = 0},
pitch_correction = -67,
pivot_h = 0.65,
pivot_v = 0.65
},
-- Function
on_eat_drop = function(self)
animalia.protect_from_despawn(self)
end,
-- Functions
utility_stack = {
{
utility = "animalia:wander_skittish",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(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
local sneaking = target:get_player_control().sneak
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
self._puncher = target
return score / 2, {self, target}
@ -99,16 +139,10 @@ creatura.register_mob("animalia:fox", {
end
},
{
utility = "animalia:walk_to_food",
utility = "animalia:walk_to_pos_and_interact",
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.7, {self, food_item}
if math.random(14) < 2 then
return 0.7, {self, get_food_pos, eat_dropped_food, nil, 12}
end
return 0
end
@ -137,33 +171,38 @@ creatura.register_mob("animalia:fox", {
end
}
},
on_eat_drop = function(self)
animalia.protect_from_despawn(self)
end,
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.5, 0.75)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
death_func = animalia.death_func,
on_rightclick = function(self, clicker)
if not clicker:is_player() then return end
local name = clicker:get_player_name()
local passive = true
if animalia.feed(self, clicker, passive, passive) then
if animalia.feed(self, clicker, true, true) then
return
end
if animalia.set_nametag(self, clicker) then
return
end
end,
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_sub = vector.subtract
creatura.register_mob("animalia:frog", {
-- Stats
max_health = 5,
armor_groups = {fleshy = 200},
damage = 0,
speed = 4,
tracking_range = 16,
despawn_after = 2500,
-- Entity Physics
stepheight = 1.1,
max_fall = 0,
turn_rate = 10,
bouyancy_multiplier = 0,
hydrodynamics_multiplier = 0.3,
-- 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 = {
local function poison_effect(object)
object:punch(object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 1},
})
end
local hitboxes = {
{-0.25, 0, -0.25, 0.2, 0.4, 0.25},
{-0.4, 0, -0.4, 0.4, 0.5, 0.4},
{-0.15, 0, -0.15, 0.15, 0.3, 0.15}
}
local animations = {
{
stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
float = {range = {x = 90, y = 90}, speed = 1, frame_blend = 0.3, loop = true},
swim = {range = {x = 90, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
walk = {range = {x = 50, y = 80}, speed = 50, frame_blend = 0.3, loop = true},
run = {range = {x = 50, y = 80}, speed = 60, frame_blend = 0.3, loop = true}
},
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
random = {
name = "animalia_frog",
gain = 0.5,
distance = 32,
variations = 3
}
{
stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 50, y = 79}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 50, y = 79}, speed = 30, frame_blend = 0.3, loop = true},
warn = {range = {x = 90, y = 129}, speed = 30, frame_blend = 0.3, loop = true},
punch = {range = {x = 140, y = 160}, speed = 30, frame_blend = 0.1, loop = false},
float = {range = {x = 170, y = 209}, speed = 10, frame_blend = 0.3, loop = true},
swim = {range = {x = 220, y = 239}, speed = 20, frame_blend = 0.3, loop = true}
},
follow = {
"butterflies:butterfly_red",
"butterflies:butterfly_white",
"butterflies:butterfly_violet"
},
head_data = {
offset = {x = 0, y = 0.43, z = 0},
pitch_correction = -15,
pivot_h = 0.3,
pivot_v = 0.3
},
-- Function
utility_stack = {
{
stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 50, y = 69}, speed = 30, frame_blend = 0.3, loop = true},
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},
swim = {range = {x = 130, y = 149}, speed = 20, frame_blend = 0.3, loop = true}
}
}
local utility_stacks = {
{ -- Tree Frog
{
utility = "animalia:wander",
step_delay = 0.25,
@ -117,7 +97,7 @@ creatura.register_mob("animalia:frog", {
step_delay = 0.25,
get_score = function(self)
if not self.in_liquid
and self.growth_scale <= 0.6 then
and self.growth_scale < 0.8 then
return 1, {self}
end
return 0
@ -159,38 +139,318 @@ creatura.register_mob("animalia:frog", {
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)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.trust = self:recall("trust") or {}
for i = 1, 15 do
local frame = 120 + i
local anim = {range = {x = frame, y = frame}, speed = 1, frame_blend = 0.3, loop = false}
self.animations["tongue_" .. i] = anim
local mesh_no = self.mesh_no
-- 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,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.2, 0.2)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self:timer(random(5, 15)) then
self:play_sound("random")
end
local props = self.object:get_properties()
if self.growth_scale <= 0.6
and props.mesh ~= "animalia_tadpole.b3d" then
self.object:set_properties({
mesh = "animalia_tadpole.b3d"
})
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if self.mesh_no ~= 2 then return end
if animalia.feed(self, clicker, false, true) then
animalia.add_trust(self, clicker, 1)
return
@ -199,11 +459,21 @@ creatura.register_mob("animalia:frog", {
return
end
end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
self.trust[puncher:get_player_name()] = 0
self:memorize("trust", self.trust)
local name = puncher:is_player() and puncher:get_player_name()
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
})
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))
if not colors[color_no] then return end
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({
textures = {texture .. "^" .. pattern}
})
end
creatura.register_mob("animalia:horse", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_horse.b3d",
textures = {
"animalia_horse_1.png",
"animalia_horse_2.png",
@ -98,19 +83,18 @@ creatura.register_mob("animalia:horse", {
"animalia_horse_5.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,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
-- Creatura Props
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 = {
alter_child_pitch = true,
random = {
@ -129,10 +113,27 @@ creatura.register_mob("animalia:horse", {
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 = {
{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 = {
["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
@ -144,30 +145,6 @@ creatura.register_mob("animalia:horse", {
pivot_h = 1,
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 = "animalia:wander_group",
@ -244,6 +221,60 @@ creatura.register_mob("animalia:horse", {
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)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
@ -258,16 +289,10 @@ creatura.register_mob("animalia:horse", {
self:memorize("speed", self.speed)
self:memorize("jump_power", self.jump_power)
if self.saddled then
local texture = self.object:get_properties().textures[1]
self.object:set_properties({
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}
}
self:set_saddle(true)
end
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self)
@ -275,48 +300,53 @@ creatura.register_mob("animalia:horse", {
animalia.update_lasso_effects(self)
animalia.random_sound(self)
end,
death_func = function(self)
if self.rider then
animalia.mount(self, self.rider)
end
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
end
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
return
end
local tool = clicker:get_wielded_item()
local tool_name = clicker:get_wielded_item():get_name()
if self.owner
and self.owner == clicker:get_player_name() then
if self.saddled
and tool_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
local wielded_name = clicker:get_wielded_item():get_name()
if wielded_name == "" then
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,
on_punch = function(self, puncher, ...)
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, ...)
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 --
---------
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 abs = math.abs
local vec_dist = vector.distance
@ -42,46 +31,51 @@ local function get_home_pos(self)
end
creatura.register_mob("animalia:owl", {
-- Stats
max_health = 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
-- Engine Props
visual_size = {x = 10, y = 10},
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 = {
width = 0.15,
height = 0.3
},
visual_size = {x = 10, y = 10},
textures = {
"animalia_owl.png"
},
animations = {
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},
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},
eat = {range = {x = 161, y = 179}, speed = 20, frame_blend = 0.1, loop = false}
},
-- Misc
makes_footstep_sound = true,
follow = {"animalia:rat_raw"},
drops = {
{name = "animalia:feather", min = 1, max = 2, chance = 1}
},
-- Animalia Props
flee_puncher = true, -- TODO
catch_with_net = true,
catch_with_lasso = false,
--sounds = {},
follow = {"animalia:rat_raw"},
-- Function
roost_action = animalia.action_roost,
-- Functions
on_eat_drop = function(self)
animalia.protect_from_despawn(self)
get_home_pos(self)
end,
is_home = function(pos, home_pos)
if abs(pos.x - home_pos.x) < 0.5
and abs(pos.z - home_pos.z) < 0.5 then
@ -97,11 +91,13 @@ creatura.register_mob("animalia:owl", {
end
return false
end,
wander_action = creatura.action_move,
utility_stack = {
{
utility = "animalia:aerial_wander",
step_delay = 0.25,
--step_delay = 0.25,
get_score = function(self)
if not self.is_landed
or self.in_liquid then
@ -126,7 +122,7 @@ creatura.register_mob("animalia:owl", {
local home = animalia.is_day and self.home_position
if home
and vec_dist(pos, home) < 8 then
return 0.6, {self}
return 0.2, {self}
end
return 0
end
@ -141,15 +137,19 @@ creatura.register_mob("animalia:owl", {
end
local food_item = animalia.get_dropped_food(self, "animalia:rat_raw")
if food_item then
return 0.7, {self, food_item}
return 0.3, {self, food_item}
end
return 0
end
},
{
utility = "animalia:glide_attack_target",
utility = "animalia:raptor_hunt",
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()
if tgt_pos then
return 0.4, {self, target}
@ -158,6 +158,7 @@ creatura.register_mob("animalia:owl", {
end
},
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
@ -174,6 +175,7 @@ creatura.register_mob("animalia:owl", {
get_home_pos(self)
end
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
@ -186,11 +188,13 @@ creatura.register_mob("animalia:owl", {
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:fly_to_roost" then
@ -203,6 +207,7 @@ creatura.register_mob("animalia:owl", {
end
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, false) then
return
@ -211,7 +216,11 @@ creatura.register_mob("animalia:owl", {
return
end
end,
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 --
---------
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", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_pig.b3d",
female_textures = {
"animalia_pig_1.png",
"animalia_pig_2.png",
@ -58,21 +21,18 @@ creatura.register_mob("animalia:pig", {
"animalia_pig_2.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,
consumable_nodes = destroyable_crops,
birth_count = 2,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
-- Creatura Props
max_health = 20,
damage = 2,
speed = 3,
tracking_range = 12,
despawn_after = 500,
stepheight = 1.1,
sounds = {
random = {
name = "animalia_pig_random",
name = "animalia_pig",
gain = 1.0,
distance = 8
},
@ -87,11 +47,33 @@ creatura.register_mob("animalia:pig", {
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 = {
{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 = "animalia:wander",
@ -101,11 +83,11 @@ creatura.register_mob("animalia:pig", {
end
},
{
utility = "animalia:eat_from_turf",
step_delay = 0.25,
utility = "animalia:walk_to_pos_and_interact",
get_score = function(self)
if math.random(25) < 2 then
return 0.2, {self}
if math.random(6) < 2
or self:get_utility() == "animalia:walk_to_pos_and_interact" then
return 0.2, {self, animalia.find_crop, animalia.eat_crop}
end
return 0
end
@ -134,21 +116,22 @@ creatura.register_mob("animalia:pig", {
},
animalia.global_utils.basic_flee
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
animalia.head_tracking(self)
animalia.update_lasso_effects(self)
animalia.random_sound(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
death_func = animalia.death_func,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
@ -157,7 +140,11 @@ creatura.register_mob("animalia:pig", {
return
end
end,
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 --
----------
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", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_rat.b3d",
textures = {
"animalia_rat_1.png",
"animalia_rat_2.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 = {
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},
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}
},
-- Misc
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = false,
makes_footstep_sound = false,
drops = {
{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 = "animalia:wander",
@ -61,21 +100,17 @@ creatura.register_mob("animalia:rat", {
end
},
{
utility = "animalia:eat_crop",
utility = "animalia:walk_to_pos_and_interact",
get_score = function(self)
-- Eat Crops
if math.random(6) < 2
or self:get_utility() == "animalia:eat_crop" then
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, "eat"}
end
return 0
end
},
{
utility = "animalia:steal_from_chest",
get_score = function(self)
-- Steal From Chest
if math.random(12) < 2
or self:get_utility() == "animalia:steal_from_chest" then
return 0.2, {self}
or self:get_utility() == "animalia:walk_to_pos_and_interact" then
return 0.3, {self, find_chest, take_food_from_chest, "eat"}
end
return 0
end
@ -95,26 +130,33 @@ creatura.register_mob("animalia:rat", {
end
}
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.set_nametag(self, clicker) then
return
end
end,
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 --
--------------
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
creatura.register_mob("animalia:reindeer", {
-- Stats
max_health = 20,
armor_groups = {fleshy = 125},
-- Engine Props
visual_size = {x = 10, y = 10},
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,
speed = 3,
boid_seperation = 1,
tracking_range = 16,
despawn_after = 1500,
-- Entity Physics
tracking_range = 12,
max_boids = 4,
despawn_after = 500,
stepheight = 1.1,
turn_rate = 4,
-- Visuals
mesh = "animalia_reindeer.b3d",
--sound = {},
hitbox = {
width = 0.45,
height = 0.9
},
visual_size = {x = 10, y = 10},
textures = {"animalia_reindeer.png"},
child_textures = {"animalia_reindeer_calf.png"},
animations = {
stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true},
run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
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}
},
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
follow = animalia.food_wheat,
drops = {
{name = "animalia:venison_raw", min = 1, max = 3, chance = 1},
{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 = {
{
name = "default:dirt_with_grass",
@ -68,12 +58,11 @@ creatura.register_mob("animalia:reindeer", {
pivot_h = 1,
pivot_v = 1
},
move_chance = 2,
idle_time = 1,
-- Function
-- Functions
utility_stack = {
{
utility = "animalia:wander_group",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
@ -113,21 +102,21 @@ creatura.register_mob("animalia:reindeer", {
},
animalia.global_utils.basic_flee
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
animalia.head_tracking(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
death_func = animalia.death_func,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
@ -136,7 +125,11 @@ creatura.register_mob("animalia:reindeer", {
return
end
end,
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 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 = {
{"black", "Black", "#000000b0"},
{"blue", "Blue", "#015dbb70"},
{"brown", "Brown", "#663300a0"},
{"cyan", "Cyan", "#01ffd870"},
{"dark_green", "Dark Green", "#005b0770"},
{"dark_grey", "Dark Grey", "#303030b0"},
{"green", "Green", "#61ff0170"},
{"grey", "Grey", "#5b5b5bb0"},
{"magenta", "Magenta", "#ff05bb70"},
{"orange", "Orange", "#ff840170"},
{"pink", "Pink", "#ff65b570"},
{"red", "Red", "#ff0000a0"},
{"violet", "Violet", "#2000c970"},
{"white", "White", "#ababab00"},
{"yellow", "Yellow", "#e3ff0070"},
black = {"Black", "#000000b0"},
blue = {"Blue", "#015dbb70"},
brown = {"Brown", "#663300a0"},
cyan = {"Cyan", "#01ffd870"},
dark_green = {"Dark Green", "#005b0770"},
dark_grey = {"Dark Grey", "#303030b0"},
green = {"Green", "#61ff0170"},
grey = {"Grey", "#5b5b5bb0"},
magenta = {"Magenta", "#ff05bb70"},
orange = {"Orange", "#ff840170"},
pink = {"Pink", "#ff65b570"},
red = {"Red", "#ff0000a0"},
violet = {"Violet", "#2000c970"},
white = {"White", "#ababab00"},
yellow = {"Yellow", "#e3ff0070"},
}
creatura.register_mob("animalia:sheep", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_sheep.b3d",
textures = {
"animalia_sheep.png^animalia_sheep_wool.png"
},
child_textures = {
"animalia_sheep.png"
},
animations = {
stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 110}, speed = 40, frame_blend = 0.3, loop = true},
run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
},
-- Misc
makes_footstep_sound = true,
flee_puncher = true,
catch_with_net = true,
catch_with_lasso = true,
-- Creatura Props
max_health = 15,
armor_groups = {fleshy = 100},
damage = 0,
speed = 3,
tracking_range = 12,
max_boids = 4,
despawn_after = 500,
stepheight = 1.1,
sounds = {
random = {
name = "animalia_sheep_idle",
name = "animalia_sheep",
gain = 1.0,
distance = 8
},
@ -92,11 +60,27 @@ creatura.register_mob("animalia:sheep", {
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 = {
{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 = {
["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
@ -107,10 +91,11 @@ creatura.register_mob("animalia:sheep", {
pivot_h = 0.75,
pivot_v = 0.85
},
-- Function
-- Functions
utility_stack = {
{
utility = "animalia:wander_group",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
@ -150,38 +135,34 @@ creatura.register_mob("animalia:sheep", {
},
animalia.global_utils.basic_flee
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.collected = self:recall("collected") or false
self.dye_color = self:recall("dye_color") or "white"
self.dye_hex = self:recall("dye_hex") or ""
if self.dye_color ~= "white"
and not self.collected then
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[colorize:" .. self.dye_hex .. ")"},
})
end
if self.collected then
self.object:set_properties({
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
self.attention_span = 8
self._path = {}
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
animalia.head_tracking(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
animalia.random_sound(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
death_func = animalia.death_func,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
@ -189,61 +170,61 @@ creatura.register_mob("animalia:sheep", {
if animalia.set_nametag(self, clicker) then
return
end
if self.collected
or self.growth_scale < 1 then
return
end
local tool = clicker:get_wielded_item()
local tool_name = tool:get_name()
if tool_name == "animalia:shears"
and not self.collected
and self.growth_scale > 0.9 then
local creative = minetest.is_creative_enabled(clicker)
if tool_name == "animalia:shears" then
if not minetest.get_modpath("wool") then
return
end
minetest.add_item(
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.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({
textures = {"animalia_sheep.png"},
})
if not creative then
tool:add_wear(650)
clicker:set_wielded_item(tool)
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])
self.dye_hex = self:memorize("dye_hex", color[3])
self.drops = {
{name = "animalia:mutton_raw", chance = 1, min = 1, max = 4},
{name = "wool:"..self.dye_color, chance = 2, min = 1, max = 2},
}
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[colorize:" .. color[3] .. ")"},
})
if not creative then
tool:take_item()
clicker:set_wielded_item(tool)
end
break
if tool_name:match("^dye:") then
local dye_color = tool_name:split(":")[2]
if palette[dye_color] then
self.dye_color = self:memorize("dye_color", dye_color)
self.drops = {
{name = "animalia:mutton_raw", chance = 1, min = 1, max = 4},
{name = "wool:" .. dye_color, chance = 2, min = 1, max = 2},
}
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[multiply:" .. palette[dye_color][2] .. ")"},
})
if not creative then
tool:take_item()
clicker:set_wielded_item(tool)
end
end
end
end,
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", {
-- Stats
max_health = 5,
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
-- Engine Props
visual_size = {x = 10, y = 10},
meshes = {
"animalia_clownfish.b3d",
"animalia_angelfish.b3d"
},
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 10, y = 10},
mesh_textures = {
{
"animalia_clownfish.png",
@ -36,15 +18,35 @@ creatura.register_mob("animalia:tropical_fish", {
"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 = {
swim = {range = {x = 1, y = 20}, speed = 20, frame_blend = 0.3, loop = true},
flop = {range = {x = 30, y = 40}, speed = 20, frame_blend = 0.3, loop = true},
},
-- Misc
bouyancy_multiplier = 0,
-- Animalia Props
flee_puncher = false,
catch_with_net = true,
catch_with_lasso = false,
makes_footstep_sound = false,
-- Function
-- Functions
utility_stack = {
{
utility = "animalia:aquatic_wander_school",
@ -65,29 +67,37 @@ creatura.register_mob("animalia:tropical_fish", {
end
},
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.set_nametag(self, clicker) then
return
end
end,
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:blue_tang", "animalia:tropical_fish")

View file

@ -2,71 +2,63 @@
-- 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", {
-- Stats
max_health = 10,
armor_groups = {fleshy = 150},
damage = 0,
speed = 4,
tracking_range = 16,
despawn_after = 1500,
-- Entity Physics
stepheight = 1.1,
max_fall = 8,
-- Visuals
-- Engine Props
visual_size = {x = 10, y = 10},
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 = {
width = 0.3,
height = 0.6
},
visual_size = {x = 7, y = 7},
female_textures = {"animalia_turkey_hen.png"},
male_textures = {"animalia_turkey_tom.png"},
child_textures = {"animalia_turkey_chick.png"},
animations = {
stand = {range = {x = 0, y = 0}, speed = 1, frame_blend = 0.3, loop = true},
walk = {range = {x = 10, y = 30}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 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},
},
-- Misc
makes_footstep_sound = true,
follow = animalia.food_seeds,
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,
catch_with_net = 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 = {
offset = {x = 0, y = 0.15, z = 0},
pitch_correction = 45,
@ -75,38 +67,19 @@ creatura.register_mob("animalia:turkey", {
},
move_chance = 2,
idle_time = 1,
-- Function
add_child = function(self)
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,
-- Functions
utility_stack = {
{
utility = "animalia:wander_group",
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
},
{
utility = "animalia:swim_to_Land",
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.5, {self}
@ -117,6 +90,7 @@ creatura.register_mob("animalia:turkey", {
animalia.global_utils.basic_follow,
{
utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name) then
@ -127,10 +101,23 @@ creatura.register_mob("animalia:turkey", {
},
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)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.75, 0.75)
@ -147,20 +134,24 @@ creatura.register_mob("animalia:turkey", {
animalia.random_drop_item(self, "animalia:turkey_egg", 10)
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
return
end
if animalia.set_nametag(self, clicker) then
return
end
animalia.set_nametag(self, clicker)
end,
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
creatura.register_mob("animalia:wolf", {
-- Stats
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
},
-- Engine Props
visual_size = {x = 10, y = 10},
mesh = "animalia_wolf.b3d",
textures = {
"animalia_wolf_1.png",
"animalia_wolf_2.png",
"animalia_wolf_3.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,
-- 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_lasso = true,
assist_owner = true,
follow = follow,
consumable_nodes = {},
head_data = {
offset = {x = 0, y = 0.33, z = 0},
pitch_correction = -67,
pivot_h = 0.65,
pivot_v = 0.65
offset = {x = 0, y = 0.22, z = 0},
pitch_correction = -35,
pivot_h = 0.45,
pivot_v = 0.45
},
-- Function
-- Functions
utility_stack = {
{
utility = "animalia:wander_skittish",
@ -156,6 +159,7 @@ creatura.register_mob("animalia:wolf", {
end
}
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
@ -169,17 +173,36 @@ creatura.register_mob("animalia:wolf", {
end
end
end,
step_func = function(self)
animalia.step_timers(self)
animalia.head_tracking(self, 0.5, 0.75)
animalia.head_tracking(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
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)
if not clicker:is_player() then return end
local name = clicker:get_player_name()
@ -213,6 +236,7 @@ creatura.register_mob("animalia:wolf", {
self:memorize("order", self.order)
end
end,
on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
creatura.basic_punch_func(self, puncher, time_from_last_punch, tool_capabilities, direction, damage)
local name = puncher:is_player() and puncher:get_player_name()
@ -234,21 +258,9 @@ creatura.register_mob("animalia:wolf", {
end
self._target = puncher
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