Update 0.6.3
20
.luacheckrc
Normal file
|
@ -0,0 +1,20 @@
|
|||
max_line_length = 120
|
||||
|
||||
globals = {
|
||||
"minetest",
|
||||
"VoxelArea",
|
||||
"mob_core",
|
||||
"creatura",
|
||||
"animalia",
|
||||
"farming",
|
||||
"mcl_player",
|
||||
"player_api"
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
"vector",
|
||||
"ItemStack",
|
||||
table = {fields = {"copy"}}
|
||||
}
|
||||
|
||||
ignore = {"212/self", "212/this"}
|
36
api/api.lua
|
@ -83,13 +83,13 @@ local function activate_nametag(self)
|
|||
})
|
||||
end
|
||||
|
||||
local animate_player = {}
|
||||
animalia.animate_player = {}
|
||||
|
||||
if minetest.get_modpath("default")
|
||||
and minetest.get_modpath("player_api") then
|
||||
animate_player = player_api.set_animation
|
||||
animalia.animate_player = player_api.set_animation
|
||||
elseif minetest.get_modpath("mcl_player") then
|
||||
animate_player = mcl_player.player_set_animation
|
||||
animalia.animate_player = mcl_player.player_set_animation
|
||||
end
|
||||
|
||||
-----------------------
|
||||
|
@ -100,7 +100,7 @@ function animalia.rotate_to_pitch(self)
|
|||
local rot = self.object:get_rotation()
|
||||
if self._anim == "fly" then
|
||||
local vel = vec_normal(self.object:get_velocity())
|
||||
local step = math.min(self.dtime * 5, abs(diff(rot.x, vel.y)) % (pi2))
|
||||
local step = min(self.dtime * 5, abs(diff(rot.x, vel.y)) % (pi2))
|
||||
local n_rot = interp_angle(rot.x, vel.y, step)
|
||||
self.object:set_rotation({
|
||||
x = clamp(n_rot, -0.75, 0.75),
|
||||
|
@ -249,8 +249,8 @@ end
|
|||
|
||||
function animalia.particle_spawner(pos, texture, type, min_pos, max_pos)
|
||||
type = type or "float"
|
||||
min_pos = min_pos or vec_sub(pos, 2)
|
||||
max_pos = max_pos or vec_add(pos, 2)
|
||||
min_pos = min_pos or vec_sub(pos, 1)
|
||||
max_pos = max_pos or vec_add(pos, 1)
|
||||
if type == "float" then
|
||||
minetest.add_particlespawner({
|
||||
amount = 16,
|
||||
|
@ -384,6 +384,7 @@ function animalia.set_nametag(self, clicker)
|
|||
end
|
||||
|
||||
function animalia.initialize_api(self)
|
||||
-- Set Gender
|
||||
self.gender = self:recall("gender") or nil
|
||||
if not self.gender then
|
||||
local genders = {"male", "female"}
|
||||
|
@ -391,10 +392,14 @@ function animalia.initialize_api(self)
|
|||
-- Reset Texture ID
|
||||
self.texture_no = nil
|
||||
end
|
||||
|
||||
-- Taming/Breeding
|
||||
self.food = self:recall("food") or 0
|
||||
self.gotten = self:recall("gotten") or false
|
||||
self.breeding = false
|
||||
self.breeding_cooldown = self:recall("breeding_cooldown") or 0
|
||||
|
||||
-- Textures/Scale
|
||||
activate_nametag(self)
|
||||
if self.growth_scale then
|
||||
self:memorize("growth_scale", self.growth_scale) -- This is for spawning children
|
||||
|
@ -580,12 +585,11 @@ function animalia.mount(self, player, params)
|
|||
})
|
||||
player:set_eye_offset()
|
||||
if minetest.get_modpath("player_api") then
|
||||
animate_player(player, "stand", 30)
|
||||
animalia.animate_player(player, "stand", 30)
|
||||
if player_api.player_attached then
|
||||
player_api.player_attached[plyr_name] = false
|
||||
end
|
||||
end
|
||||
self.rider = nil
|
||||
return
|
||||
end
|
||||
if minetest.get_modpath("player_api") then
|
||||
|
@ -593,10 +597,10 @@ function animalia.mount(self, player, params)
|
|||
end
|
||||
self.rider = player
|
||||
player:set_attach(self.object, "Torso", params.pos, params.rot)
|
||||
player:set_eye_offset({x = 0, y = 25, z = 0}, {x = 0, y = 15, z = 15})
|
||||
player:set_eye_offset({x = 0, y = 20, z = 5}, {x = 0, y = 15, z = 15})
|
||||
self:clear_utility()
|
||||
minetest.after(0.4, function()
|
||||
animate_player(player, "sit" , 30)
|
||||
animalia.animate_player(player, "sit" , 30)
|
||||
end)
|
||||
end
|
||||
|
||||
|
@ -630,6 +634,18 @@ function animalia.eat_crop(self, pos)
|
|||
return true
|
||||
end
|
||||
|
||||
function animalia.eat_turf(mob, pos)
|
||||
for name, sub_name in pairs(mob.consumable_nodes) do
|
||||
if minetest.get_node(pos).name == name then
|
||||
--add_break_particle(turf_pos)
|
||||
minetest.set_node(pos, {name = sub_name})
|
||||
mob.collected = mob:memorize("collected", false)
|
||||
--creatura.action_idle(mob, 1, "eat")
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--------------
|
||||
-- Spawning --
|
||||
--------------
|
||||
|
|
1197
api/behaviors.lua
|
@ -447,6 +447,8 @@ minetest.register_craftitem("animalia:libri_animalia", {
|
|||
description = "Libri Animalia",
|
||||
inventory_image = "animalia_libri_animalia.png",
|
||||
stack_max = 1,
|
||||
groups = {book = 1},
|
||||
|
||||
on_place = function(itemstack, player)
|
||||
local meta = itemstack:get_meta()
|
||||
if meta:get_string("pages") ~= "" then meta:set_string("pages", "") end
|
||||
|
|
133
api/spawning.lua
|
@ -2,7 +2,9 @@
|
|||
-- Spawning --
|
||||
--------------
|
||||
|
||||
local function is_value_in_table(tbl, val)
|
||||
local random = math.random
|
||||
|
||||
local function table_contains(tbl, val)
|
||||
for _, v in pairs(tbl) do
|
||||
if v == val then
|
||||
return true
|
||||
|
@ -11,13 +13,13 @@ local function is_value_in_table(tbl, val)
|
|||
return false
|
||||
end
|
||||
|
||||
local common_spawn_chance = tonumber(minetest.settings:get("animalia_common_chance")) or 30000
|
||||
local common_spawn_chance = tonumber(minetest.settings:get("animalia_common_chance")) or 45000
|
||||
|
||||
local ambient_spawn_chance = tonumber(minetest.settings:get("animalia_ambient_chance")) or 6000
|
||||
local ambient_spawn_chance = tonumber(minetest.settings:get("animalia_ambient_chance")) or 9000
|
||||
|
||||
local pest_spawn_chance = tonumber(minetest.settings:get("animalia_pest_chance")) or 2000
|
||||
local pest_spawn_chance = tonumber(minetest.settings:get("animalia_pest_chance")) or 3000
|
||||
|
||||
local predator_spawn_chance = tonumber(minetest.settings:get("animalia_predator_chance")) or 30000
|
||||
local predator_spawn_chance = tonumber(minetest.settings:get("animalia_predator_chance")) or 45000
|
||||
|
||||
-- Get Biomes --
|
||||
|
||||
|
@ -44,6 +46,9 @@ end)
|
|||
|
||||
creatura.register_abm_spawn("animalia:chicken", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 3,
|
||||
|
@ -62,9 +67,11 @@ creatura.register_abm_spawn("animalia:cat", {
|
|||
neighbors = {"group:wood"}
|
||||
})
|
||||
|
||||
|
||||
creatura.register_abm_spawn("animalia:cow", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 3,
|
||||
|
@ -86,6 +93,9 @@ creatura.register_abm_spawn("animalia:fox", {
|
|||
|
||||
creatura.register_abm_spawn("animalia:horse", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 3,
|
||||
|
@ -119,6 +129,9 @@ creatura.register_abm_spawn("animalia:owl", {
|
|||
|
||||
creatura.register_abm_spawn("animalia:pig", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 2,
|
||||
|
@ -129,6 +142,9 @@ creatura.register_abm_spawn("animalia:pig", {
|
|||
|
||||
creatura.register_abm_spawn("animalia:reindeer", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 6,
|
||||
|
@ -139,6 +155,9 @@ creatura.register_abm_spawn("animalia:reindeer", {
|
|||
|
||||
creatura.register_abm_spawn("animalia:sheep", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 3,
|
||||
|
@ -150,6 +169,9 @@ creatura.register_abm_spawn("animalia:sheep", {
|
|||
|
||||
creatura.register_abm_spawn("animalia:turkey", {
|
||||
chance = common_spawn_chance,
|
||||
chance_on_load = 64,
|
||||
spawn_active = true,
|
||||
spawn_on_load = true,
|
||||
min_height = 0,
|
||||
max_height = 1024,
|
||||
min_group = 3,
|
||||
|
@ -234,12 +256,12 @@ 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
|
||||
if table_contains(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
|
||||
elseif table_contains(animalia.registered_biome_groups["temperate"].biomes, biome_name)
|
||||
or table_contains(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
|
||||
elseif table_contains(animalia.registered_biome_groups["grassland"].biomes, biome_name) then
|
||||
self:set_mesh(2)
|
||||
else
|
||||
self.object:remove()
|
||||
|
@ -259,3 +281,94 @@ creatura.register_abm_spawn("animalia:tropical_fish", {
|
|||
nodes = {"group:water"},
|
||||
neighbors = {"group:coral"}
|
||||
})
|
||||
|
||||
-- World Gen Spawning
|
||||
|
||||
minetest.register_node("animalia:spawner", {
|
||||
description = "???",
|
||||
drawtype = "airlike",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
sunlight_propagates = true,
|
||||
groups = {oddly_breakable_by_hand = 1, not_in_creative_inventory = 1}
|
||||
})
|
||||
|
||||
minetest.register_decoration({
|
||||
name = "animalia:world_gen_spawning",
|
||||
deco_type = "simple",
|
||||
place_on = {"group:stone", "group:sand", "group:soil"},
|
||||
sidelen = 1,
|
||||
fill_ratio = 0.0001, -- One node per chunk
|
||||
decoration = "animalia:spawner"
|
||||
})
|
||||
|
||||
local function do_on_spawn(pos, obj)
|
||||
local name = obj and obj:get_luaentity().name
|
||||
if not name then return end
|
||||
local spawn_functions = creatura.registered_on_spawns[name] or {}
|
||||
|
||||
if #spawn_functions > 0 then
|
||||
for _, func in ipairs(spawn_functions) do
|
||||
func(obj:get_luaentity(), pos)
|
||||
if not obj:get_yaw() then break end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_abm({
|
||||
label = "[animalia] World Gen Spawning",
|
||||
nodenames = {"animalia:spawner"},
|
||||
interval = 10, -- TODO: Set this to 1 if world is singleplayer and just started
|
||||
chance = 16,
|
||||
|
||||
action = function(pos, _, active_object_count)
|
||||
minetest.remove_node(pos)
|
||||
|
||||
if active_object_count > 8 then return end
|
||||
|
||||
local spawnable_mobs = {}
|
||||
|
||||
local current_biome = minetest.get_biome_name(minetest.get_biome_data(pos).biome)
|
||||
|
||||
local spawn_definitions = creatura.registered_mob_spawns
|
||||
|
||||
for mob, def in pairs(spawn_definitions) do
|
||||
if mob:match("^animalia:")
|
||||
and def.biomes
|
||||
and table_contains(def.biomes, current_biome) then
|
||||
table.insert(spawnable_mobs, mob)
|
||||
end
|
||||
end
|
||||
|
||||
if #spawnable_mobs > 0 then
|
||||
local mob_to_spawn = spawnable_mobs[math.random(#spawnable_mobs)]
|
||||
local spawn_definition = creatura.registered_mob_spawns[mob_to_spawn]
|
||||
|
||||
local group_size = random(spawn_definition.min_group or 1, spawn_definition.max_group or 1)
|
||||
local obj
|
||||
|
||||
if group_size > 1 then
|
||||
local offset
|
||||
local spawn_pos
|
||||
for _ = 1, group_size do
|
||||
offset = group_size * 0.5
|
||||
spawn_pos = creatura.get_ground_level({
|
||||
x = pos.x + random(-offset, offset),
|
||||
y = pos.y,
|
||||
z = pos.z + random(-offset, offset)
|
||||
}, 3)
|
||||
|
||||
if not creatura.is_pos_moveable(spawn_pos, 0.5, 0.5) then
|
||||
spawn_pos = pos
|
||||
end
|
||||
|
||||
obj = minetest.add_entity(spawn_pos, mob_to_spawn)
|
||||
do_on_spawn(spawn_pos, obj)
|
||||
end
|
||||
else
|
||||
obj = minetest.add_entity(pos, mob_to_spawn)
|
||||
do_on_spawn(pos, obj)
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
|
|
@ -3,11 +3,20 @@ local mod_storage = minetest.get_mod_storage()
|
|||
local data = {
|
||||
spawn_points = minetest.deserialize(mod_storage:get_string("spawn_points")) or {},
|
||||
libri_font_size = minetest.deserialize(mod_storage:get_string("libri_font_size")) or {},
|
||||
bound_horse = minetest.deserialize(mod_storage:get_string("bound_horse")) or {}
|
||||
}
|
||||
|
||||
local function save()
|
||||
mod_storage:set_string("spawn_points", minetest.serialize(data.spawn_points))
|
||||
mod_storage:set_string("libri_font_size", minetest.serialize(data.libri_font_size))
|
||||
|
||||
for name, bound_data in pairs(data.bound_horse) do
|
||||
if bound_data
|
||||
and bound_data.obj then
|
||||
data.bound_horse[name].obj = nil
|
||||
end
|
||||
end
|
||||
mod_storage:set_string("bound_horse", minetest.serialize(data.bound_horse))
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(save)
|
||||
|
|
4
init.lua
|
@ -6,6 +6,7 @@ local storage = dofile(path .. "/api/storage.lua")
|
|||
|
||||
animalia.spawn_points = storage.spawn_points
|
||||
animalia.libri_font_size = storage.libri_font_size
|
||||
animalia.bound_horse = storage.bound_horse
|
||||
|
||||
animalia.pets = {}
|
||||
|
||||
|
@ -79,12 +80,10 @@ minetest.register_on_mods_loaded(function()
|
|||
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)
|
||||
|
@ -105,6 +104,7 @@ animalia.animals = {
|
|||
"animalia:fox",
|
||||
"animalia:frog",
|
||||
"animalia:horse",
|
||||
"animalia:opossum",
|
||||
"animalia:owl",
|
||||
"animalia:pig",
|
||||
"animalia:rat",
|
||||
|
|
|
@ -63,8 +63,10 @@ creatura.register_mob("animalia:chicken", {
|
|||
{name = "animalia:feather", min = 1, max = 3, chance = 2}
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
group_wander = true,
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
catch_with_lasso = true,
|
||||
|
|
21
mobs/cow.lua
|
@ -2,9 +2,6 @@
|
|||
-- Cow --
|
||||
---------
|
||||
|
||||
local random = math.random
|
||||
|
||||
|
||||
creatura.register_mob("animalia:cow", {
|
||||
-- Engine Props
|
||||
visual_size = {x = 10, y = 10},
|
||||
|
@ -65,7 +62,7 @@ creatura.register_mob("animalia:cow", {
|
|||
},
|
||||
animations = {
|
||||
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
|
||||
walk = {range = {x = 71, y = 89}, speed = 20, frame_blend = 0.3, loop = true},
|
||||
walk = {range = {x = 71, y = 89}, speed = 15, frame_blend = 0.3, loop = true},
|
||||
run = {range = {x = 71, y = 89}, speed = 30, frame_blend = 0.3, loop = true},
|
||||
},
|
||||
follow = animalia.food_wheat,
|
||||
|
@ -75,6 +72,10 @@ creatura.register_mob("animalia:cow", {
|
|||
},
|
||||
fancy_collide = false,
|
||||
|
||||
-- Behavior Parameters
|
||||
is_grazing_mob = true,
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
|
@ -100,16 +101,6 @@ creatura.register_mob("animalia:cow", {
|
|||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:eat_turf",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if random(64) < 2 then
|
||||
return 0.2, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:swim_to_land",
|
||||
step_delay = 0.25,
|
||||
|
@ -183,7 +174,7 @@ creatura.register_mob("animalia:cow", {
|
|||
if inv:room_for_item("main", {name = "animalia:bucket_milk"}) then
|
||||
clicker:get_inventory():add_item("main", "animalia:bucket_milk")
|
||||
else
|
||||
local pos = self:get_pos("floor")
|
||||
local pos = self.object:get_pos()
|
||||
pos.y = pos.y + 0.5
|
||||
minetest.add_item(pos, {name = "animalia:bucket_milk"})
|
||||
end
|
||||
|
|
|
@ -77,8 +77,10 @@ creatura.register_mob("animalia:fox", {
|
|||
"animalia:poultry_raw"
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_skittish_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
skittish_wander = true,
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
catch_with_lasso = true,
|
||||
|
|
116
mobs/frog.lua
|
@ -5,9 +5,79 @@
|
|||
local random = math.random
|
||||
|
||||
local vec_add = vector.add
|
||||
local vec_dir = vector.direction
|
||||
local vec_dist = vector.distance
|
||||
local vec_sub = vector.subtract
|
||||
|
||||
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
|
||||
|
||||
local function get_bug_pos(self)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
local food = minetest.find_nodes_in_area(
|
||||
vec_sub(pos, 3),
|
||||
vec_add(pos, 3),
|
||||
self.follow
|
||||
) or {}
|
||||
|
||||
return #food > 0 and food[1]
|
||||
end
|
||||
|
||||
local function eat_bug(self)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
||||
local bug = get_bug_pos(self)
|
||||
if not bug then return end
|
||||
|
||||
local dir = vec_dir(pos, bug)
|
||||
local dist = vec_dist(pos, bug)
|
||||
local frame = math.floor(dist * 10)
|
||||
|
||||
self.object:set_yaw(dir2yaw(dir))
|
||||
animalia.move_head(self, dir2yaw(dir), dir.y)
|
||||
creatura.action_idle(self, 0.4, "tongue_" .. frame)
|
||||
|
||||
minetest.remove_node(bug)
|
||||
return true
|
||||
end
|
||||
|
||||
local function poison_effect(object)
|
||||
object:punch(object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
|
@ -67,15 +137,10 @@ local utility_stacks = {
|
|||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:eat_bug",
|
||||
utility = "animalia:walk_to_pos_and_interact",
|
||||
get_score = function(self)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
if random(12) < 2 then
|
||||
local food = minetest.find_nodes_in_area(vec_sub(pos, 1.5), vec_add(pos, 1.5), self.follow)
|
||||
if food[1] then
|
||||
return 0.3, {self, food[1]}
|
||||
end
|
||||
if math.random(2) < 2 then
|
||||
return 0.3, {self, get_bug_pos, eat_bug, nil, 0}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
@ -158,22 +223,16 @@ local utility_stacks = {
|
|||
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.3, {self, food_item}
|
||||
if math.random(8) < 2 then
|
||||
return 0.3, {self, get_food_pos, eat_dropped_food, nil, 12}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:warn_attack_target",
|
||||
utility = "animalia:attack_target",
|
||||
get_score = function(self)
|
||||
local target = creatura.get_nearby_player(self) or creatura.get_nearby_object(self, "animalia:rat")
|
||||
if target then
|
||||
|
@ -330,6 +389,18 @@ local head_data = {
|
|||
}
|
||||
}
|
||||
|
||||
local follow = {
|
||||
{
|
||||
"butterflies:butterfly_white",
|
||||
"butterflies:butterfly_violet",
|
||||
"butterflies:butterfly_red"
|
||||
},
|
||||
{
|
||||
"animalia:rat_raw"
|
||||
},
|
||||
{}
|
||||
}
|
||||
|
||||
creatura.register_mob("animalia:frog", {
|
||||
-- Engine Props
|
||||
visual_size = {x = 10, y = 10},
|
||||
|
@ -374,9 +445,7 @@ creatura.register_mob("animalia:frog", {
|
|||
height = 0.3
|
||||
},
|
||||
animations = {},
|
||||
follow = {
|
||||
"animalia:rat_raw"
|
||||
},
|
||||
follow = {},
|
||||
drops = {},
|
||||
fancy_collide = false,
|
||||
bouyancy_multiplier = 0,
|
||||
|
@ -431,6 +500,7 @@ creatura.register_mob("animalia:frog", {
|
|||
end
|
||||
elseif mesh_no == 2 then
|
||||
self.object:set_armor_groups({fleshy = 50})
|
||||
self.warn_before_attack = true
|
||||
end
|
||||
end,
|
||||
|
||||
|
@ -441,6 +511,10 @@ creatura.register_mob("animalia:frog", {
|
|||
if self:timer(random(5, 15)) then
|
||||
self:play_sound("random")
|
||||
end
|
||||
|
||||
if not self.mesh_vars_set then
|
||||
self.follow = follow[self.mesh_no]
|
||||
end
|
||||
end,
|
||||
|
||||
death_func = function(self)
|
||||
|
|
197
mobs/horse.lua
|
@ -4,18 +4,110 @@
|
|||
|
||||
local random = math.random
|
||||
|
||||
local follows = {}
|
||||
-- Horse Inventory
|
||||
|
||||
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)
|
||||
local form_obj = {}
|
||||
|
||||
local function create_horse_inventory(self)
|
||||
if not self.owner then return end
|
||||
local inv_name = "animalia:horse_" .. self.owner
|
||||
local inv = minetest.create_detached_inventory(inv_name, {
|
||||
allow_move = function(_, _, _, _, _, count)
|
||||
return count
|
||||
end,
|
||||
allow_put = function(_, _, _, stack)
|
||||
return stack:get_count()
|
||||
end,
|
||||
allow_take = function(_, _, _, stack)
|
||||
return stack:get_count()
|
||||
end
|
||||
})
|
||||
inv:set_size("main", 12)
|
||||
inv:set_width("main", 4)
|
||||
return inv
|
||||
end
|
||||
|
||||
local function serialize_horse_inventory(self)
|
||||
if not self.owner then return end
|
||||
local inv_name = "animalia:horse_" .. self.owner
|
||||
local inv = minetest.get_inventory({type = "detached", name = inv_name})
|
||||
if not inv then return end
|
||||
local list = inv:get_list("main")
|
||||
local stored = {}
|
||||
for k, item in ipairs(list) do
|
||||
local itemstr = item:to_string()
|
||||
if itemstr ~= "" then
|
||||
stored[k] = itemstr
|
||||
end
|
||||
end
|
||||
self._inventory = self:memorize("_inventory", minetest.serialize(stored))
|
||||
end
|
||||
|
||||
local function get_form(self, player_name)
|
||||
local inv = create_horse_inventory(self)
|
||||
if inv
|
||||
and self._inventory then
|
||||
inv:set_list("main", minetest.deserialize(self._inventory))
|
||||
end
|
||||
|
||||
local frame_range = self.animations["stand"].range
|
||||
local frame_loop = frame_range.x .. "," .. frame_range.y
|
||||
local texture = self:get_props().textures[1]
|
||||
local form = {
|
||||
"formspec_version[3]",
|
||||
"size[10.5,10]",
|
||||
"image[0,0;10.5,5.25;animalia_form_horse_bg.png]",
|
||||
"model[0,0.5;5,3.5;mob_mesh;animalia_horse.b3d;" .. texture .. ";-10,-130;false;false;" .. frame_loop .. ";15]",
|
||||
"list[detached:animalia:horse_" .. player_name .. ";main;5.4,0.5;4,3;]",
|
||||
"list[current_player;main;0.4,4.9;8,4;]",
|
||||
"listring[current_player;main]"
|
||||
}
|
||||
|
||||
return table.concat(form, "")
|
||||
end
|
||||
|
||||
local function close_form(player)
|
||||
local name = player:get_player_name()
|
||||
|
||||
if form_obj[name] then
|
||||
form_obj[name] = nil
|
||||
minetest.remove_detached_inventory("animalia:horse_" .. name)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local name = player:get_player_name()
|
||||
if not form_obj[name] or not form_obj[name]:get_yaw() then
|
||||
return
|
||||
end
|
||||
local obj = form_obj[name]
|
||||
if formname == "animalia:horse_forms" then
|
||||
local ent = obj and obj:get_luaentity()
|
||||
if not ent then return end
|
||||
|
||||
if fields.quit or fields.key_enter then
|
||||
form_obj[name] = nil
|
||||
serialize_horse_inventory(ent)
|
||||
minetest.remove_detached_inventory("animlaia:horse_" .. name)
|
||||
end
|
||||
end
|
||||
|
||||
if formname == "animalia:horse_inv" then
|
||||
local ent = obj and obj:get_luaentity()
|
||||
if not ent then return end
|
||||
|
||||
if fields.quit or fields.key_enter then
|
||||
form_obj[name] = nil
|
||||
serialize_horse_inventory(ent)
|
||||
minetest.remove_detached_inventory("animalia:horse_" .. name)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(close_form)
|
||||
|
||||
-- Pattern
|
||||
|
||||
local patterns = {
|
||||
"animalia_horse_pattern_1.png",
|
||||
"animalia_horse_pattern_2.png",
|
||||
|
@ -26,11 +118,11 @@ local avlbl_colors = {
|
|||
[1] = {
|
||||
"animalia_horse_2.png",
|
||||
"animalia_horse_3.png",
|
||||
"animalia_horse_6.png"
|
||||
"animalia_horse_5.png"
|
||||
},
|
||||
[2] = {
|
||||
"animalia_horse_1.png",
|
||||
"animalia_horse_6.png"
|
||||
"animalia_horse_5.png"
|
||||
},
|
||||
[3] = {
|
||||
"animalia_horse_2.png",
|
||||
|
@ -43,10 +135,6 @@ local avlbl_colors = {
|
|||
[5] = {
|
||||
"animalia_horse_2.png",
|
||||
"animalia_horse_1.png"
|
||||
},
|
||||
[6] = {
|
||||
"animalia_horse_2.png",
|
||||
"animalia_horse_1.png"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +159,8 @@ local function set_pattern(self)
|
|||
})
|
||||
end
|
||||
|
||||
-- Definition
|
||||
|
||||
creatura.register_mob("animalia:horse", {
|
||||
-- Engine Props
|
||||
visual_size = {x = 10, y = 10},
|
||||
|
@ -80,8 +170,7 @@ creatura.register_mob("animalia:horse", {
|
|||
"animalia_horse_2.png",
|
||||
"animalia_horse_3.png",
|
||||
"animalia_horse_4.png",
|
||||
"animalia_horse_5.png",
|
||||
"animalia_horse_6.png"
|
||||
"animalia_horse_5.png"
|
||||
},
|
||||
makes_footstep_sound = true,
|
||||
|
||||
|
@ -119,20 +208,23 @@ creatura.register_mob("animalia:horse", {
|
|||
},
|
||||
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},
|
||||
walk = {range = {x = 70, y = 89}, speed = 20, 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}
|
||||
punch_aoe = {range = {x = 170, y = 205}, speed = 30, frame_blend = 0.2, loop = false},
|
||||
rear = {range = {x = 130, y = 160}, speed = 20, frame_blend = 0.2, loop = false},
|
||||
eat = {range = {x = 210, y = 240}, speed = 30, frame_blend = 0.3, loop = false}
|
||||
},
|
||||
follow = follows,
|
||||
follow = animalia.food_wheat,
|
||||
drops = {
|
||||
{name = "animalia:leather", min = 1, max = 4, chance = 2}
|
||||
},
|
||||
fancy_collide = false,
|
||||
|
||||
-- Behavior Parameters
|
||||
is_grazing_mob = true,
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
group_wander = true,
|
||||
catch_with_net = true,
|
||||
catch_with_lasso = true,
|
||||
consumable_nodes = {
|
||||
|
@ -141,8 +233,8 @@ creatura.register_mob("animalia:horse", {
|
|||
},
|
||||
head_data = {
|
||||
bone = "Neck.CTRL",
|
||||
offset = {x = 0, y = 1.05, z = 0.0},
|
||||
pitch_correction = 35,
|
||||
offset = {x = 0, y = 1.4, z = 0.0},
|
||||
pitch_correction = 15,
|
||||
pivot_h = 1,
|
||||
pivot_v = 1.75
|
||||
},
|
||||
|
@ -154,16 +246,6 @@ creatura.register_mob("animalia:horse", {
|
|||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:eat_turf",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if random(64) < 2 then
|
||||
return 0.2, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:swim_to_land",
|
||||
step_delay = 0.25,
|
||||
|
@ -187,19 +269,19 @@ creatura.register_mob("animalia:horse", {
|
|||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:flee_from_target_defend",
|
||||
utility = "animalia:flee_from_target",
|
||||
get_score = function(self)
|
||||
local puncher = self._puncher
|
||||
if puncher
|
||||
and puncher:get_pos() then
|
||||
return 0.6, {self, puncher}
|
||||
return 0.6, {self, puncher, true}
|
||||
end
|
||||
self._puncher = nil
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:tame_horse",
|
||||
utility = "animalia:horse_taming",
|
||||
get_score = function(self)
|
||||
local rider = not self.owner and self.rider
|
||||
if rider
|
||||
|
@ -212,6 +294,7 @@ creatura.register_mob("animalia:horse", {
|
|||
{
|
||||
utility = "animalia:mount_horse",
|
||||
get_score = function(self)
|
||||
if not self.owner then return 0 end
|
||||
local owner = self.owner and minetest.get_player_by_name(self.owner)
|
||||
local rider = owner == self.rider and self.rider
|
||||
if rider
|
||||
|
@ -280,7 +363,13 @@ creatura.register_mob("animalia:horse", {
|
|||
animalia.initialize_api(self)
|
||||
animalia.initialize_lasso(self)
|
||||
set_pattern(self)
|
||||
|
||||
self.owner = self:recall("owner") or nil
|
||||
|
||||
if self.owner then
|
||||
self._inventory = self:recall("_inventory")
|
||||
end
|
||||
|
||||
self.rider = nil
|
||||
self.saddled = self:recall("saddled") or false
|
||||
self.max_health = self:recall("max_health") or random(30, 45)
|
||||
|
@ -300,6 +389,11 @@ creatura.register_mob("animalia:horse", {
|
|||
animalia.do_growth(self, 60)
|
||||
animalia.update_lasso_effects(self)
|
||||
animalia.random_sound(self)
|
||||
|
||||
if self.owner
|
||||
and animalia.bound_horse[self.owner] then
|
||||
animalia.bound_horse[self.owner].last_pos = self.object:get_pos()
|
||||
end
|
||||
end,
|
||||
|
||||
death_func = function(self)
|
||||
|
@ -315,22 +409,31 @@ creatura.register_mob("animalia:horse", {
|
|||
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 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 wielded_name == "animalia:saddle" then
|
||||
self:set_saddle(true)
|
||||
return
|
||||
end
|
||||
|
||||
if clicker:get_player_control().sneak
|
||||
and owner then
|
||||
minetest.show_formspec(name, "animalia:horse_forms", get_form(self, name))
|
||||
form_obj[name] = self.object
|
||||
elseif wielded_name == "" then
|
||||
animalia.mount(self, clicker, {rot = {x = -65, y = 180, z = 0}, pos = {x = 0, y = 0.75, z = 0.6}})
|
||||
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,
|
||||
|
||||
|
@ -344,6 +447,16 @@ creatura.register_mob("animalia:horse", {
|
|||
return
|
||||
end
|
||||
animalia.punch(self, puncher, ...)
|
||||
end,
|
||||
|
||||
on_detach_child = function(self, child)
|
||||
if child
|
||||
and self.rider == child then
|
||||
self.rider = nil
|
||||
child:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
||||
child:set_properties({visual_size = {x = 1, y = 1}})
|
||||
animalia.animate_player(child, "stand", 30)
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
|
|
212
mobs/opossum.lua
Normal file
|
@ -0,0 +1,212 @@
|
|||
---------
|
||||
-- Fox --
|
||||
---------
|
||||
|
||||
local vec_dir, vec_dist = vector.direction, vector.distance
|
||||
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:opossum", {
|
||||
-- Engine Props
|
||||
visual_size = {x = 10, y = 10},
|
||||
mesh = "animalia_opossum.b3d",
|
||||
textures = {
|
||||
"animalia_opossum.png"
|
||||
},
|
||||
makes_footstep_sound = false,
|
||||
|
||||
-- Creatura Props
|
||||
max_health = 5,
|
||||
armor_groups = {fleshy = 100},
|
||||
damage = 2,
|
||||
speed = 4,
|
||||
tracking_range = 16,
|
||||
max_boids = 0,
|
||||
despawn_after = 500,
|
||||
stepheight = 1.1,
|
||||
sound = {},
|
||||
hitbox = {
|
||||
width = 0.25,
|
||||
height = 0.4
|
||||
},
|
||||
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 = 45, frame_blend = 0.3, loop = true},
|
||||
feint = {range = {x = 130, y = 130}, speed = 45, frame_blend = 0.3, loop = false}
|
||||
},
|
||||
follow = {
|
||||
"animalia:song_bird_egg",
|
||||
"animalia:rat_raw",
|
||||
"animalia:mutton_raw",
|
||||
"animalia:beef_raw",
|
||||
"animalia:porkchop_raw",
|
||||
"animalia:poultry_raw"
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_skittish_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
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
|
||||
},
|
||||
|
||||
-- Functions
|
||||
utility_stack = {
|
||||
{
|
||||
utility = "animalia:wander",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:swim_to_land",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if self.in_liquid then
|
||||
return 0.3, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:attack_target",
|
||||
get_score = function(self)
|
||||
local target = self._target or creatura.get_nearby_object(self, {"animalia:rat"})
|
||||
local tgt_pos = target and target:get_pos()
|
||||
if tgt_pos
|
||||
and self:is_pos_safe(tgt_pos) then
|
||||
return 0.4, {self, target}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:idle",
|
||||
get_score = function(self)
|
||||
local target = self._puncher or creatura.get_nearby_player(self)
|
||||
local pos, tgt_pos = self.object:get_pos(), target and target:get_pos()
|
||||
if not pos then return end
|
||||
if not tgt_pos then self._puncher = nil return 0 end
|
||||
local sneaking = target:get_player_control().sneak
|
||||
if not sneaking then
|
||||
local dist = vec_dist(pos, tgt_pos)
|
||||
local score = (self.tracking_range - dist) / self.tracking_range
|
||||
self._puncher = target
|
||||
return score / 3, {self, 5, "feint"}
|
||||
end
|
||||
self._puncher = nil
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:walk_to_pos_and_interact",
|
||||
get_score = function(self)
|
||||
if math.random(14) < 2 then
|
||||
return 0.7, {self, get_food_pos, eat_dropped_food, nil, 12}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:follow_player",
|
||||
get_score = function(self)
|
||||
local lasso_tgt = self._lassod_to
|
||||
local lasso = type(lasso_tgt) == "string" and minetest.get_player_by_name(lasso_tgt)
|
||||
if lasso
|
||||
and lasso:get_pos() then
|
||||
return 0.6, {self, lasso, true}
|
||||
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) then
|
||||
return 0.7, {self}
|
||||
end
|
||||
return 0
|
||||
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 = animalia.death_func,
|
||||
|
||||
on_rightclick = function(self, clicker)
|
||||
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_item("animalia:opossum", {
|
||||
col1 = "d0602d",
|
||||
col2 = "c9c9c9"
|
||||
})
|
50
mobs/owl.lua
|
@ -4,8 +4,46 @@
|
|||
|
||||
local abs = math.abs
|
||||
|
||||
local vec_dir = vector.direction
|
||||
local vec_dist = vector.distance
|
||||
|
||||
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
|
||||
|
||||
local function get_home_pos(self)
|
||||
local pos = self.object:get_pos()
|
||||
if not pos then return end
|
||||
|
@ -128,16 +166,10 @@ creatura.register_mob("animalia:owl", {
|
|||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:fly_to_food",
|
||||
utility = "animalia:fly_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, "animalia:rat_raw")
|
||||
if food_item then
|
||||
return 0.3, {self, food_item}
|
||||
if math.random(1) < 2 then
|
||||
return 0.3, {self, get_food_pos, eat_dropped_food, nil, 12}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
|
|
@ -61,6 +61,9 @@ creatura.register_mob("animalia:pig", {
|
|||
{name = "animalia:porkchop_raw", min = 1, max = 3, chance = 1}
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
|
|
|
@ -75,6 +75,9 @@ creatura.register_mob("animalia:rat", {
|
|||
{name = "animalia:rat_raw", min = 1, max = 1, chance = 1}
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_skittish_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
-- Reindeer --
|
||||
--------------
|
||||
|
||||
local random = math.random
|
||||
|
||||
creatura.register_mob("animalia:reindeer", {
|
||||
-- Engine Props
|
||||
visual_size = {x = 10, y = 10},
|
||||
|
@ -20,7 +18,23 @@ creatura.register_mob("animalia:reindeer", {
|
|||
max_boids = 4,
|
||||
despawn_after = 500,
|
||||
stepheight = 1.1,
|
||||
--sound = {},
|
||||
sounds = {
|
||||
random = {
|
||||
name = "animalia_reindeer",
|
||||
gain = 0.5,
|
||||
distance = 8
|
||||
},
|
||||
hurt = {
|
||||
name = "animalia_reindeer_hurt",
|
||||
gain = 0.5,
|
||||
distance = 8
|
||||
},
|
||||
death = {
|
||||
name = "animalia_reindeer_death",
|
||||
gain = 0.5,
|
||||
distance = 8
|
||||
}
|
||||
},
|
||||
hitbox = {
|
||||
width = 0.45,
|
||||
height = 0.9
|
||||
|
@ -37,8 +51,11 @@ creatura.register_mob("animalia:reindeer", {
|
|||
{name = "animalia:leather", min = 1, max = 3, chance = 2}
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_grazing_mob = true,
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
group_wander = true,
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
catch_with_lasso = true,
|
||||
|
@ -53,7 +70,7 @@ creatura.register_mob("animalia:reindeer", {
|
|||
}
|
||||
},
|
||||
head_data = {
|
||||
offset = {x = 0, y = 0.7, z = 0},
|
||||
offset = {x = 0, y = 0.55, z = 0},
|
||||
pitch_correction = -45,
|
||||
pivot_h = 1,
|
||||
pivot_v = 1
|
||||
|
@ -68,16 +85,6 @@ creatura.register_mob("animalia:reindeer", {
|
|||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:eat_turf",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if random(64) < 2 then
|
||||
return 0.2, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:swim_to_land",
|
||||
step_delay = 0.25,
|
||||
|
@ -113,6 +120,7 @@ creatura.register_mob("animalia:reindeer", {
|
|||
animalia.head_tracking(self)
|
||||
animalia.do_growth(self, 60)
|
||||
animalia.update_lasso_effects(self)
|
||||
animalia.random_sound(self)
|
||||
end,
|
||||
|
||||
death_func = animalia.death_func,
|
||||
|
|
|
@ -66,8 +66,8 @@ creatura.register_mob("animalia:sheep", {
|
|||
},
|
||||
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},
|
||||
walk = {range = {x = 70, y = 89}, speed = 20, frame_blend = 0.3, loop = true},
|
||||
run = {range = {x = 100, y = 119}, speed = 30, frame_blend = 0.3, loop = true},
|
||||
eat = {range = {x = 130, y = 150}, speed = 20, frame_blend = 0.3, loop = false}
|
||||
},
|
||||
follow = animalia.food_wheat,
|
||||
|
@ -76,8 +76,11 @@ creatura.register_mob("animalia:sheep", {
|
|||
minetest.get_modpath("wool") and {name = "wool:white", min = 1, max = 3, chance = 2} or nil
|
||||
},
|
||||
|
||||
-- Behavior Parameters
|
||||
is_grazing_mob = true,
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
group_wander = true,
|
||||
flee_puncher = true,
|
||||
catch_with_net = true,
|
||||
catch_with_lasso = true,
|
||||
|
@ -101,16 +104,6 @@ creatura.register_mob("animalia:sheep", {
|
|||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:eat_turf",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if random(64) < 2 then
|
||||
return 0.2, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:swim_to_land",
|
||||
step_delay = 0.25,
|
||||
|
@ -177,7 +170,7 @@ creatura.register_mob("animalia:sheep", {
|
|||
|
||||
local tool = clicker:get_wielded_item()
|
||||
local tool_name = tool:get_name()
|
||||
local creative = minetest.is_creative_enabled(clicker)
|
||||
local creative = minetest.is_creative_enabled(clicker:get_player_name())
|
||||
|
||||
if tool_name == "animalia:shears" then
|
||||
if not minetest.get_modpath("wool") then
|
||||
|
|
|
@ -29,7 +29,7 @@ creatura.register_mob("animalia:tropical_fish", {
|
|||
max_boids = 6,
|
||||
boid_seperation = 0.3,
|
||||
despawn_after = 200,
|
||||
max_fall = 3,
|
||||
max_fall = 0,
|
||||
stepheight = 1.1,
|
||||
hitbox = {
|
||||
width = 0.15,
|
||||
|
@ -39,7 +39,11 @@ creatura.register_mob("animalia:tropical_fish", {
|
|||
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},
|
||||
},
|
||||
bouyancy_multiplier = 0,
|
||||
liquid_submergence = 1,
|
||||
liquid_drag = 0,
|
||||
|
||||
-- Animalia Behaviors
|
||||
is_aquatic_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
flee_puncher = false,
|
||||
|
@ -54,18 +58,7 @@ creatura.register_mob("animalia:tropical_fish", {
|
|||
get_score = function(self)
|
||||
return 0.1, {self}
|
||||
end
|
||||
},
|
||||
{
|
||||
utility = "animalia:flop",
|
||||
step_delay = 0.25,
|
||||
get_score = function(self)
|
||||
if not self.in_liquid then
|
||||
self:hurt(1)
|
||||
return 1, {self}
|
||||
end
|
||||
return 0
|
||||
end
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
activate_func = function(self)
|
||||
|
|
|
@ -75,8 +75,11 @@ creatura.register_mob("animalia:wolf", {
|
|||
},
|
||||
follow = follow,
|
||||
|
||||
-- Behavior Parameters
|
||||
is_skittish_mob = true,
|
||||
is_herding_mob = true,
|
||||
|
||||
-- Animalia Props
|
||||
skittish_wander = true,
|
||||
assist_owner = true,
|
||||
flee_puncher = false,
|
||||
catch_with_net = true,
|
||||
|
|
BIN
models/animalia_opossum.b3d
Normal file
BIN
sounds/animalia_horse_whistle.ogg
Normal file
BIN
sounds/morbiu.ogg
Normal file
BIN
sounds/reindeer/animalia_reindeer.1.ogg
Normal file
BIN
sounds/reindeer/animalia_reindeer.2.ogg
Normal file
BIN
sounds/reindeer/animalia_reindeer_death.ogg
Normal file
BIN
sounds/reindeer/animalia_reindeer_hurt.ogg
Normal file
20
storage.lua
Normal file
|
@ -0,0 +1,20 @@
|
|||
local mod_storage = minetest.get_mod_storage()
|
||||
|
||||
local data = {
|
||||
bound_horse = minetest.deserialize(mod_storage:get_string("bound_horse")) or {},
|
||||
}
|
||||
|
||||
local function save()
|
||||
mod_storage:set_string("bound_horse", minetest.serialize(data.bound_horse))
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(save)
|
||||
minetest.register_on_leaveplayer(save)
|
||||
|
||||
local function periodic_save()
|
||||
save()
|
||||
minetest.after(120, periodic_save)
|
||||
end
|
||||
minetest.after(120, periodic_save)
|
||||
|
||||
return data
|
BIN
textures/formspecs/animalia_form_horse_bg.png
Normal file
After Width: | Height: | Size: 6 KiB |
BIN
textures/formspecs/animalia_horse_call_icon.png
Normal file
After Width: | Height: | Size: 765 B |
BIN
textures/formspecs/animalia_horse_inv_icon.png
Normal file
After Width: | Height: | Size: 768 B |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 7 KiB After Width: | Height: | Size: 8.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 12 KiB |
BIN
textures/opossum/animalia_opossum.png
Normal file
After Width: | Height: | Size: 7.4 KiB |