Minor Behavior Overhaul

This commit is contained in:
ElCeejo 2024-01-04 11:15:02 -08:00
parent 20c55da709
commit 09f2dce19f
30 changed files with 2118 additions and 3130 deletions

View file

@ -81,48 +81,9 @@ creatura.register_mob("animalia:bat", {
-- Functions
utility_stack = {
{
utility = "animalia:aerial_wander",
step_delay = 0.25,
get_score = function(self)
local pos = self.object:get_pos()
if not pos then return end
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 dist = vec_dist(pos, plyr_pos)
self._target = player
self.is_landed = false
return (self.tracking_range - dist) / self.tracking_range, {self}
end
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:fly_to_roost",
get_score = function(self)
local pos = self.object:get_pos()
if not pos then return end
local home = animalia.is_day and self.home_position
if (home
and home.x
and vec_dist(pos, home) < 8)
or self.is_landed then
return 0.6, {self}
end
return 0
end
}
animalia.mob_ai.fly_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.bat_seek_home
},
is_home = function(pos, home_pos)

View file

@ -2,10 +2,6 @@
-- Cat --
---------
local random = math.random
local vec_dist, vec_add, vec_sub = vector.distance, vector.add, vector.subtract
local follow = {
"animalia:poultry_raw"
}
@ -17,24 +13,6 @@ 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", {
-- Engine Props
visual_size = {x = 10, y = 10},
@ -101,6 +79,9 @@ creatura.register_mob("animalia:cat", {
follow = follow,
drops = {},
-- Behavior Parameters
is_skittish_mob = true,
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
@ -111,119 +92,17 @@ creatura.register_mob("animalia:cat", {
pivot_h = 0.4,
pivot_v = 0.4
},
skittish_wander = true,
-- 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:walk_to_pos_and_interact",
step_delay = 0.25,
get_score = function(self)
if random(2) < 2 then
return 0.2, {self, find_glass_vessel, destroy_glass_vessel, nil, 10}
end
return 0
end
},
{
utility = "animalia:bother_player",
step_delay = 0.25,
get_score = function(self)
if random(24) > 1 then return 0 end
local owner = self.owner and minetest.get_player_by_name(self.owner)
local pos = self.object:get_pos()
if not pos then return end
local trust = self.trust[self.owner] or 0
if trust > 3
and owner
and vec_dist(pos, owner:get_pos()) < self.tracking_range then
return 0.2, {self, owner}
end
return 0
end
},
{
utility = "animalia:stay",
step_delay = 0.25,
get_score = function(self)
local trust = (self.owner and self.trust[self.owner]) or 0
if trust < 5 then return 0 end
local order = self.order or "wander"
if order == "sit" then
return 0.5, {self}
end
return 0
end
},
{
utility = "animalia:play_with_player",
step_delay = 0.25,
get_score = function(self)
if self.trust_cooldown > 0 then return 0 end
local owner = self.owner and minetest.get_player_by_name(self.owner)
if owner
and owner:get_wielded_item():get_name() == "animalia:cat_toy" then
return 0.6, {self, owner}
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)
local trust = (self.owner and self.trust[self.owner]) or 0
local owner = self.owner and self.order == "follow" and trust > 4 and minetest.get_player_by_name(self.owner)
local force = (lasso and lasso ~= false) or (owner and owner ~= false)
local player = (force and (owner or lasso)) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.6, {self, player, force}
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.7, {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) then
return 0.8, {self}
end
return 0
end
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.cat_seek_vessel,
animalia.mob_ai.cat_stay,
--animalia.mob_ai.cat_play
animalia.mob_ai.cat_follow_owner,
animalia.mob_ai.basic_attack,
animalia.mob_ai.basic_breed
},
activate_func = function(self)

View file

@ -81,36 +81,11 @@ creatura.register_mob("animalia:chicken", {
-- 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.5, {self}
end
return 0
end
},
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
return 0.4, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
add_child = function(self)

View file

@ -94,36 +94,11 @@ creatura.register_mob("animalia:cow", {
-- 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
},
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
return 0.5, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
activate_func = function(self)

View file

@ -2,45 +2,6 @@
-- 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:fox", {
-- Engine Props
visual_size = {x = 10, y = 10},
@ -79,6 +40,10 @@ creatura.register_mob("animalia:fox", {
-- Behavior Parameters
is_skittish_mob = true,
attack_list = {
"animalia:chicken",
"animalia:rat"
},
-- Animalia Props
flee_puncher = true,
@ -93,85 +58,13 @@ creatura.register_mob("animalia:fox", {
-- 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", "animalia:chicken"})
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:flee_from_target",
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 / 2, {self, target}
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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.basic_attack,
animalia.mob_ai.fox_flee,
animalia.mob_ai.basic_seek_food,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed
},
on_eat_drop = function(self)

View file

@ -4,80 +4,6 @@
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,
@ -119,252 +45,30 @@ local animations = {
local utility_stacks = {
{ -- Tree 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_pos_and_interact",
get_score = function(self)
if math.random(2) < 2 then
return 0.3, {self, get_bug_pos, eat_bug, nil, 0}
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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_wander,
animalia.mob_ai.frog_seek_bug,
animalia.mob_ai.frog_breed,
animalia.mob_ai.basic_flee,
animalia.mob_ai.frog_flop,
animalia.mob_ai.frog_seek_water
},
{ -- 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_pos_and_interact",
get_score = function(self)
if math.random(8) < 2 then
return 0.3, {self, get_food_pos, eat_dropped_food, nil, 12}
end
return 0
end
},
{
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
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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_wander,
animalia.mob_ai.basic_seek_food,
animalia.mob_ai.basic_attack,
animalia.mob_ai.frog_breed,
animalia.mob_ai.frog_flop,
animalia.mob_ai.frog_seek_water
},
{
{
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
}
{ -- Poison Dart Frog
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_wander,
animalia.mob_ai.frog_breed,
animalia.mob_ai.basic_flee,
animalia.mob_ai.frog_flop,
animalia.mob_ai.frog_seek_water
}
}

View file

@ -239,49 +239,13 @@ creatura.register_mob("animalia:horse", {
pivot_v = 1.75
},
utility_stack = {
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee,
{
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
},
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
return 0.5, {self}
end
return 0
end
},
{
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, true}
end
self._puncher = nil
return 0
end
},
{
utility = "animalia:horse_taming",
utility = "animalia:horse_tame",
get_score = function(self)
local rider = not self.owner and self.rider
if rider
@ -292,7 +256,7 @@ creatura.register_mob("animalia:horse", {
end
},
{
utility = "animalia:mount_horse",
utility = "animalia:horse_ride",
get_score = function(self)
if not self.owner then return 0 end
local owner = self.owner and minetest.get_player_by_name(self.owner)
@ -389,11 +353,6 @@ 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)

View file

@ -1,45 +1,6 @@
---------
-- 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
-------------
-- Opossum --
-------------
creatura.register_mob("animalia:opossum", {
-- Engine Props
@ -59,6 +20,7 @@ creatura.register_mob("animalia:opossum", {
max_boids = 0,
despawn_after = 500,
stepheight = 1.1,
max_fall = 8,
sound = {},
hitbox = {
width = 0.25,
@ -81,6 +43,7 @@ creatura.register_mob("animalia:opossum", {
-- Behavior Parameters
is_skittish_mob = true,
attack_list = {"animalia:rat"},
-- Animalia Props
flee_puncher = true,
@ -95,85 +58,13 @@ creatura.register_mob("animalia:opossum", {
-- 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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.basic_attack,
animalia.mob_ai.opossum_feint,
animalia.mob_ai.basic_seek_food,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed
},
on_eat_drop = function(self)

View file

@ -4,46 +4,8 @@
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
@ -133,62 +95,11 @@ creatura.register_mob("animalia:owl", {
wander_action = creatura.action_move,
utility_stack = {
{
utility = "animalia:aerial_wander",
--step_delay = 0.25,
get_score = function(self)
if not self.is_landed
or self.in_liquid then
return 0.1, {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)
local plyr_pos = player and player:get_pos()
if plyr_pos then
local dist = vector.distance(pos, plyr_pos)
if dist < 3 then
return 0
end
end
local home = animalia.is_day and self.home_position
if home
and vec_dist(pos, home) < 8 then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:fly_to_pos_and_interact",
get_score = function(self)
if math.random(1) < 2 then
return 0.3, {self, get_food_pos, eat_dropped_food, nil, 12}
end
return 0
end
},
{
utility = "animalia:raptor_hunt",
get_score = function(self)
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}
end
return 0
end
},
animalia.mob_ai.fly_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.bat_seek_home,
animalia.mob_ai.fly_seek_food,
animalia.mob_ai.eagle_attack
},
activate_func = function(self)

View file

@ -78,46 +78,12 @@ creatura.register_mob("animalia:pig", {
-- Functions
utility_stack = {
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
end
},
{
utility = "animalia:walk_to_pos_and_interact",
get_score = function(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
},
{
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
},
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
return 0.5, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.basic_seek_crop,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
activate_func = function(self)

View file

@ -2,47 +2,6 @@
-- 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", {
-- Engine Props
visual_size = {x = 10, y = 10},
@ -85,53 +44,11 @@ creatura.register_mob("animalia:rat", {
-- 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:walk_to_pos_and_interact",
get_score = function(self)
-- Eat Crops
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, "eat"}
end
-- Steal From Chest
if math.random(12) < 2
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
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local target = creatura.get_nearby_object(self, {"animalia:fox", "animalia:cat"})
if not target then
target = creatura.get_nearby_player(self)
end
if target
and target:get_pos() then
return 0.6, {self, target}
end
return 0
end
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.basic_seek_crop,
animalia.mob_ai.rat_seek_chest,
animalia.mob_ai.basic_flee
},
activate_func = function(self)
@ -162,4 +79,4 @@ creatura.register_mob("animalia:rat", {
creatura.register_spawn_item("animalia:rat", {
col1 = "605a55",
col2 = "ff936f"
})
})

View file

@ -78,36 +78,11 @@ creatura.register_mob("animalia:reindeer", {
-- 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
},
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
return 0.5, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
activate_func = function(self)

View file

@ -97,36 +97,11 @@ creatura.register_mob("animalia:sheep", {
-- 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
},
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
return 0.5, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
activate_func = function(self)

View file

@ -54,6 +54,9 @@ creatura.register_mob("animalia:song_bird", {
{name = "animalia:feather", min = 1, max = 1, chance = 2}
},
-- Behavior Parameters
uses_boids = true,
-- Animalia Props
flee_puncher = true,
catch_with_net = true,
@ -63,41 +66,9 @@ creatura.register_mob("animalia:song_bird", {
-- 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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.fly_landing_wander,
animalia.mob_ai.fly_seek_land
},
activate_func = function(self)

View file

@ -52,13 +52,7 @@ creatura.register_mob("animalia:tropical_fish", {
-- Functions
utility_stack = {
{
utility = "animalia:aquatic_wander_school",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
}
animalia.mob_ai.swim_wander
},
activate_func = function(self)

View file

@ -70,36 +70,11 @@ creatura.register_mob("animalia:turkey", {
-- 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.5, {self}
end
return 0
end
},
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
return 0.4, {self}
end
return 0
end
},
animalia.global_utils.basic_flee
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_breed,
animalia.mob_ai.basic_flee
},
add_child = function(self)

View file

@ -2,20 +2,7 @@
-- Wolf --
----------
local function shared_owner(obj1, obj2)
if not obj1 or not obj2 then return false end
obj1 = creatura.is_valid(obj1)
obj2 = creatura.is_valid(obj2)
if obj1
and obj2
and obj1:get_luaentity()
and obj2:get_luaentity() then
obj1 = obj1:get_luaentity()
obj2 = obj2:get_luaentity()
return obj1.owner and obj2.owner and obj1.owner == obj2.owner
end
return false
end
local follow = {
"animalia:mutton_raw",
@ -94,74 +81,12 @@ creatura.register_mob("animalia:wolf", {
-- 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 order = self.order or "wander"
if order ~= "wander" then return 0 end
local target = self._target or creatura.get_nearby_object(self, "animalia:sheep")
if target
and not shared_owner(self, target) then
return 0.4, {self, target}
end
return 0
end
},
{
utility = "animalia:stay",
step_delay = 0.25,
get_score = function(self)
local order = self.order or "wander"
if order == "sit" then
return 0.5, {self}
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)
local owner = self.owner and self.order == "follow" and minetest.get_player_by_name(self.owner)
local force = (lasso and lasso ~= false) or owner
local player = (force and (owner or lasso)) or creatura.get_nearby_player(self)
if player
and (self:follow_wielded_item(player)
or force) then
return 0.6, {self, player, force}
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
}
animalia.mob_ai.basic_wander,
animalia.mob_ai.swim_seek_land,
animalia.mob_ai.tamed_stay,
animalia.mob_ai.tamed_follow_owner,
animalia.mob_ai.basic_attack,
animalia.mob_ai.basic_breed
},
activate_func = function(self)