This commit is contained in:
ElCeejo 2022-08-12 22:17:42 -07:00
parent 78e7b8bb44
commit eccc33cea5
108 changed files with 4818 additions and 5250 deletions

View file

@ -2,30 +2,6 @@
-- Bat --
---------
local function get_ceiling_positions(pos, range)
local walkable = minetest.find_nodes_in_area(
{x = pos.x + range, y = pos.y + range, z = pos.z + range},
{x = pos.x - range, y = pos.y, z = pos.z - range},
animalia.walkable_nodes
)
if #walkable < 1 then return {} end
local output = {}
for i = 1, #walkable do
local i_pos = walkable[i]
local under = {
x = i_pos.x,
y = i_pos.y - 1,
z = i_pos.z
}
if minetest.get_node(under).name == "air"
and minetest.registered_nodes[minetest.get_node(i_pos).name].walkable then
table.insert(output, i_pos)
end
end
return output
end
local guano_accumulation = minetest.settings:get_bool("guano_accumulation")
-- Math --
@ -51,6 +27,33 @@ local function vec_raise(v, n)
return {x = v.x, y = v.y + n, z = v.z}
end
---------------
-- Utilities --
---------------
local function get_roost(pos, range)
local walkable = minetest.find_nodes_in_area(
{x = pos.x + range, y = pos.y + range, z = pos.z + range},
{x = pos.x - range, y = pos.y, z = pos.z - range},
animalia.walkable_nodes
)
if #walkable < 1 then return end
local roosts = {}
for i = 1, #walkable do
local i_pos = walkable[i]
local n_pos = {
x = i_pos.x,
y = i_pos.y - 1,
z = i_pos.z
}
if creatura.get_node_def(n_pos).name == "air"
and minetest.line_of_sight(pos, n_pos) then
table.insert(roosts, n_pos)
end
end
return roosts[random(#roosts)]
end
local function is_node_walkable(name)
local def = minetest.registered_nodes[name]
return def and def.walkable
@ -84,7 +87,7 @@ creatura.register_mob("animalia:bat", {
stand = {range = {x = 1, y = 40}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 50, y = 90}, speed = 30, frame_blend = 0.3, loop = true},
fly = {range = {x = 100, y = 140}, speed = 80, frame_blend = 0.3, loop = true},
latch = {range = {x = 150, y = 150}, speed = 1, frame_blend = 0, loop = false}
cling = {range = {x = 150, y = 150}, speed = 1, frame_blend = 0, loop = false}
},
-- Misc
sounds = {
@ -103,80 +106,63 @@ creatura.register_mob("animalia:bat", {
"butterflies:butterfly_violet"
},
-- Function
step_delay = 0.25,
roost_action = animalia.action_cling,
utility_stack = {
[1] = {
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
if self.is_landed then
return 0.1, {self}
end
return 0
return 0.1, {self}
end
},
[2] = {
utility = "animalia:aerial_swarm",
{
utility = "animalia:aerial_wander",
step_delay = 0.25,
get_score = function(self)
if self:get_utility() == "animalia:return_to_home"
or self:get_utility() == "animalia:wander" then
local pos = self.object:get_pos()
local player = creatura.get_nearby_player(self)
if player
and player:get_pos()
and not player:get_player_control().sneak then
local dist = vector.distance(pos, player:get_pos())
self._nearby_player = player
self.is_landed = false
return (12 - dist) * 0.1, {self, 1}
end
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 trust = self.trust[player:get_player_name() or ""] or 0
local dist = vec_dist(pos, plyr_pos)
self._target = player
self.is_landed = false
return (12 - (dist + trust)) * 0.1, {self}
end
if self.in_liquid
or not self.is_landed then
return 0.11, {self, 1}
return 0.2, {self}
end
return 0
end
},
[3] = {
utility = "animalia:land",
{
utility = "animalia:fly_to_land",
get_score = function(self)
if not self.is_landed
and not self.touching_ground then
return 0.12, {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
},
[4] = {
utility = "animalia:return_to_home",
utility = "animalia:fly_to_roost",
get_score = function(self)
if not self.home_position then return 0 end
local player = self._nearby_player
if player
and player:get_pos() then
local pos = self.object:get_pos()
local dist = vector.distance(pos, player:get_pos())
if dist < 9 then
return 0
end
end
local time = (minetest.get_timeofday() * 24000) or 0
local is_day = time < 19500 and time > 4500
if is_day then
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 then
return 0.6, {self}
end
return 0
end
},
[5] = {
utility = "animalia:find_home",
get_score = function(self)
if self.home_position then return 0 end
local pos = self.object:get_pos()
local range = self.tracking_range
local ceiling = get_ceiling_positions(pos, range / 2)
if not ceiling[1] then return 0 end
return 1, {self}
end
}
},
activate_func = function(self)
@ -184,32 +170,40 @@ creatura.register_mob("animalia:bat", {
animalia.initialize_lasso(self)
self.home_position = self:recall("home_position") or nil
self.is_landed = self:recall("is_landed") or false
self.stamina = self:recall("stamina") or 30
self.trust = self:recall("trust") or {}
if not self.home_position then
local roost = get_roost(self.object:get_pos(), 8)
if roost then
self.home_position = self:memorize("home_position", roost)
end
end
end,
step_func = function(self)
animalia.step_timers(self)
--animalia.head_tracking(self, 0.75, 0.75)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self.stamina > 0 then
if not self.is_landed then
self.stamina = self:memorize("stamina", self.stamina - self.dtime)
else
self.stamina = self:memorize("stamina", self.stamina + self.dtime)
animalia.rotate_to_pitch(self)
local pos = self.object:get_pos()
if not pos then return end
if self:timer(random(10,15)) then
if random(4) < 2 then
self.is_landed = not self.is_landed
end
if self.stamina > 25
and self.is_landed then
self.is_landed = self:memorize("is_landed", false)
if not self.home_position
or creatura.get_node_def(self.home_position).walkable then
local roost = get_roost(pos, 8)
if roost then
self.home_position = self:memorize("home_position", roost)
end
end
else
self.stamina = self:memorize("stamina", self.stamina + self.dtime)
self.is_landed = self:memorize("is_landed", true)
end
if self._anim == "fly" then
local vel_y = self.object:get_velocity().y
local vel_y = vector.normalize(self.object:get_velocity()).y
local rot = self.object:get_rotation()
local n_rot = rot.x + (vel_y - rot.x) * 0.2
self.object:set_rotation({
x = clamp(vel_y * 0.25, -0.75, 0.75),
x = clamp(n_rot, -0.75, 0.75),
y = rot.y,
z = rot.z
})
@ -218,8 +212,7 @@ creatura.register_mob("animalia:bat", {
self:play_sound("random")
if guano_accumulation
and random(16) < 2
and self:get_utility() == "animalia:return_to_home" then
local pos = self.object:get_pos()
and self:get_utility() == "animalia:fly_to_roost" then
pos = {
x = floor(pos.x + 0.5),
y = floor(pos.y + 0.5),
@ -229,7 +222,7 @@ creatura.register_mob("animalia:bat", {
return
end
local fail_safe = 1
while not is_node_walkable(minetest.get_node(floor_pos).name)
while not is_node_walkable(minetest.get_node(pos).name)
and fail_safe < 16 do
pos.y = pos.y - 1
end
@ -260,6 +253,7 @@ creatura.register_mob("animalia:bat", {
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, false) then
animalia.add_trust(self, clicker, 1)
return
end
if animalia.set_nametag(self, clicker) then

View file

@ -5,45 +5,38 @@
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
if name:match(":seed_")
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
end
end
end
end
end)
local random = math.random
local function clamp(val, min, max)
if val < min then
val = min
elseif max < val then
val = max
end
return val
end
local vec_dist = vector.distance
creatura.register_mob("animalia:bird", {
-- Stats
max_health = 5,
armor_groups = {fleshy = 200},
damage = 0,
speed = 4,
-- Stats
max_health = 5,
armor_groups = {fleshy = 200},
damage = 0,
speed = 4,
tracking_range = 16,
despawn_after = 100,
despawn_after = 100,
-- Entity Physics
stepheight = 1.1,
max_fall = 100,
max_fall = 0,
turn_rate = 6,
boid_seperation = 0.4,
-- Visuals
mesh = "animalia_bird.b3d",
hitbox = {
-- Visuals
mesh = "animalia_bird.b3d",
hitbox = {
width = 0.15,
height = 0.3
},
visual_size = {x = 7, y = 7},
visual_size = {x = 7, y = 7},
textures = {
"animalia_bird_cardinal.png",
"animalia_bird_eastern_blue.png",
@ -52,97 +45,89 @@ creatura.register_mob("animalia:bird", {
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}
fly = {range = {x = 120, y = 140}, speed = 80, frame_blend = 0.3, loop = true}
},
-- Misc
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = false,
sounds = {
cardinal = {
name = "animalia_cardinal",
gain = 0.5,
distance = 63,
name = "animalia_cardinal",
gain = 0.5,
distance = 63,
variations = 3
},
},
eastern_blue = {
name = "animalia_eastern_blue",
gain = 0.5,
distance = 63,
name = "animalia_eastern_blue",
gain = 0.5,
distance = 63,
variations = 3
},
goldfinch = {
name = "animalia_goldfinch",
gain = 0.5,
distance = 63,
},
goldfinch = {
name = "animalia_goldfinch",
gain = 0.5,
distance = 63,
variations = 3
},
},
follow = follows,
-- Function
},
},
follow = follows,
-- Function
wander_action = animalia.action_move_flock,
utility_stack = {
{
utility = "animalia:boid_wander",
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
end
},
{
utility = "animalia:aerial_flock",
utility = "animalia:aerial_wander",
step_delay = 0.25,
get_score = function(self)
if not self.is_landed then
return 0.11, {self, 1}
else
local pos = self.object:get_pos()
if self.in_liquid then
self.stamina = self:memorize("stamina", 30)
self.is_landed = false
return 0.15, {self, 0.5}
end
local player = creatura.get_nearby_player(self)
if player
and player:get_pos() then
local dist = vector.distance(pos, player:get_pos())
self.is_landed = false
return (16 - dist) * 0.1, {self, 0.5}
end
if not self.is_landed
or self.in_liquid then
return 0.2, {self}
end
return 0
end
},
{
utility = "animalia:land",
utility = "animalia:fly_to_land",
get_score = function(self)
if self.is_landed
and not self.touching_ground
and not self.in_liquid then
return 0.12, {self}
and not self.in_liquid
and creatura.sensor_floor(self, 3, true) > 2 then
return 0.3, {self}
end
return 0
end
},
{
utility = "animalia:return_to_nest",
utility = "animalia:fly_to_roost",
get_score = function(self)
if not self.home_position then
return 0
end
local player = self._nearby_player
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 pos = self.object:get_pos()
local dist = vector.distance(pos, player:get_pos())
if dist < 3 then
return 0
end
end
if not animalia.is_day then
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)
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self._tp2home = self:recall("_tp2home") or nil
@ -152,52 +137,49 @@ creatura.register_mob("animalia:bird", {
self.object:set_pos(self.home_position)
end
self.is_landed = self:recall("is_landed") or false
self.stamina = self:recall("stamina") or 40
if not self.home_position then
local pos = self.object:get_pos()
local nests = minetest.find_nodes_in_area_under_air(vector.add(pos, 4), vector.subtract(pos, 4), {"animalia:nest_song_bird"})
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)
end,
step_func = function(self)
animalia.step_timers(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if animalia.is_day
and self:timer(random(10,15)) then
if self.texture_no == 1 then
self:play_sound("cardinal")
elseif self.texture_no == 2 then
self:play_sound("eastern_blue")
else
self:play_sound("goldfinch")
animalia.rotate_to_pitch(self)
if self:timer(random(10,15)) 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 self._anim == "fly" then
local vel_y = self.object:get_velocity().y
local rot = self.object:get_rotation()
self.object:set_rotation({
x = clamp(vel_y * 0.25, -0.75, 0.75),
y = rot.y,
z = rot.z
})
end
if self.stamina > 0 then
if not self.is_landed then
self.stamina = self:memorize("stamina", self.stamina - self.dtime)
else
self.stamina = self:memorize("stamina", self.stamina + self.dtime)
if random(4) < 2 then
self.is_landed = not self.is_landed
end
if self.stamina > 25
and self.is_landed then
self.is_landed = self:memorize("is_landed", false)
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
else
self.stamina = self:memorize("stamina", self.stamina + self.dtime)
self.is_landed = self:memorize("is_landed", true)
end
if not self.is_landed
or not self.touching_ground then
@ -205,12 +187,12 @@ creatura.register_mob("animalia:bird", {
else
self.speed = 1
end
end,
death_func = function(self)
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
self:initiate_utility("animalia:die", self)
end
end,
end,
deactivate_func = function(self)
if self:get_utility()
and self:get_utility() == "animalia:return_to_nest" then
@ -238,3 +220,12 @@ creatura.register_mob("animalia:bird", {
})
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

@ -2,6 +2,10 @@
-- Cat --
---------
local random = math.random
local vec_dist = vector.distance
local follow = {
"animalia:poultry_raw"
}
@ -20,6 +24,7 @@ creatura.register_mob("animalia:cat", {
damage = 1,
speed = 5,
tracking_range = 24,
turn_rate = 9,
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
@ -34,16 +39,25 @@ creatura.register_mob("animalia:cat", {
"animalia_cat_1.png",
"animalia_cat_2.png",
"animalia_cat_3.png",
"animalia_cat_4.png"
"animalia_cat_4.png",
"animalia_cat_5.png",
"animalia_cat_6.png",
"animalia_cat_7.png",
"animalia_cat_8.png",
"animalia_cat_9.png",
"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 = 50, y = 90}, speed = 45, frame_blend = 0.3, loop = true},
run = {range = {x = 100, y = 130}, speed = 50, frame_blend = 0.3, loop = true},
sit = {range = {x = 140, y = 180}, speed = 10, frame_blend = 0.3, loop = true},
smack = {range = {x = 190, y = 210}, speed = 40, frame_blend = 0.1, 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
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
@ -70,7 +84,7 @@ creatura.register_mob("animalia:cat", {
},
follow = follow,
head_data = {
offset = {x = 0, y = 0.22, z = 0},
offset = {x = 0, y = 0.18, z = 0},
pitch_correction = -20,
pivot_h = 0.65,
pivot_v = 0.65
@ -79,7 +93,6 @@ creatura.register_mob("animalia:cat", {
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self._path = {}
self.interact_sound_cooldown = 0
self.trust_cooldown = self:recall("trust_cooldown") or 0
self.order = self:recall("order") or "wander"
@ -93,94 +106,94 @@ creatura.register_mob("animalia:cat", {
end
end,
utility_stack = {
[1] = {
utility = "animalia:skittish_wander",
{
utility = "animalia:wander_skittish",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
},
[2] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.9, {self}
return 0.3, {self}
end
return 0
end
},
[3] = {
utility = "animalia:find_and_break_glass_vessels",
{
utility = "animalia:destroy_nearby_vessel",
step_delay = 0.25,
get_score = function(self)
return math.random(10) * 0.01, {self}
end
},
[4] = {
utility = "animalia:walk_ahead_of_player",
get_score = function(self)
local player = creatura.get_nearby_player(self)
if player
and player:get_player_name() then
local trust = 0
if not self.trust[player:get_player_name()] then
self.trust[player:get_player_name()] = 0
self:memorize("trust", self.trust)
else
trust = self.trust[player:get_player_name()]
end
self._nearby_player = player
if trust > 3 then
return math.random(10) * 0.01, {self, player}
else
return 0
end
if random(24) < 2 then
return 0.2, {self}
end
return 0
end
},
[5] = {
utility = "animalia:sit",
{
utility = "animalia:bother_player",
step_delay = 0.25,
get_score = function(self)
if self.order == "sit"
and self.trust[self.owner] > 7 then
return 0.8, {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
},
[6] = {
{
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)
if self.order == "follow"
and minetest.get_player_by_name(self.owner)
and self.trust[self.owner] > 7 then
return 1, {self, minetest.get_player_by_name(self.owner)}
end
local trust = 0
local player = self._nearby_player
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
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 player:get_player_name() then
if not self.trust[player:get_player_name()] then
self.trust[player:get_player_name()] = 0
self:memorize("trust", self.trust)
else
trust = self.trust[player:get_player_name()]
end
else
return 0
end
if player:get_velocity()
and vector.length(player:get_velocity()) < 2
and self:follow_wielded_item(player)
and trust >= 4 then
return 0.6, {self, player}
elseif player:get_wielded_item():get_name() == "animalia:cat_toy" then
return 0.6, {self, player, true}
and self:follow_wielded_item(player) then
return 0.6, {self, player, force}
end
return 0
end
},
[7] = {
utility = "animalia:mammal_breed",
{
utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name) then
@ -196,9 +209,6 @@ creatura.register_mob("animalia:cat", {
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self:timer(1) then
if self.trust_cooldown > 0 then
self.trust_cooldown = self:memorize("trust_cooldown", self.trust_cooldown - 1)
end
if self.interact_sound_cooldown > 0 then
self.interact_sound_cooldown = self.interact_sound_cooldown - 1
end
@ -234,20 +244,6 @@ creatura.register_mob("animalia:cat", {
self.trust[clicker:get_player_name()] = 0
self:memorize("trust", self.trust)
end
-- Increase trust by playing
if item_name == "animalia:cat_toy"
and self:get_utility() == "animalia:follow_player" then
if trust < 10 then
self.trust[clicker:get_player_name()] = trust + 1
self:memorize("trust", self.trust)
animalia.particle_spawner(pos, "creatura_particle_green.png", "float", minppos, maxppos)
if self.interact_sound_cooldown <= 0 then
self.sounds["purr"].gain = 1
self.interact_sound_cooldown = 3
self:play_sound("purr")
end
end
end
-- Purr to indicate trust level (louder = more trust)
if clicker:get_player_control().sneak then
if self.interact_sound_cooldown <= 0 then
@ -261,7 +257,7 @@ creatura.register_mob("animalia:cat", {
or clicker:get_player_name() ~= self.owner then
return
end
if trust <= 7 then
if trust <= 5 then
if self.interact_sound_cooldown <= 0 then
self.interact_sound_cooldown = 3
self:play_sound("random")
@ -276,11 +272,19 @@ 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")
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")
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")
self.order = "wander"
self:set_utility_score(0)
end
self:memorize("order", self.order)
end

View file

@ -5,7 +5,7 @@
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
@ -19,7 +19,7 @@ creatura.register_mob("animalia:chicken", {
armor_groups = {fleshy = 150},
damage = 0,
speed = 4,
tracking_range = 16,
tracking_range = 4,
despawn_after = 1500,
-- Entity Physics
stepheight = 1.1,
@ -42,12 +42,13 @@ creatura.register_mob("animalia:chicken", {
"animalia_rooster_2.png",
"animalia_rooster_3.png"
},
child_textures = {"animalia_chick.png"},
child_textures = {"animalia_chicken_child.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 = 10, y = 30}, speed = 45, frame_blend = 0.3, loop = true},
fall = {range = {x = 40, y = 60}, speed = 70, frame_blend = 0.3, loop = true},
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
catch_with_net = true,
@ -75,61 +76,86 @@ creatura.register_mob("animalia:chicken", {
},
follow = follows,
head_data = {
offset = {x = 0, y = 0.15, z = 0},
pitch_correction = 55,
offset = {x = 0, y = 0.45, z = 0},
pitch_correction = 40,
pivot_h = 0.25,
pivot_v = 0.55
},
-- 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,
utility_stack = {
[1] = {
utility = "animalia:wander",
{
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:resist_fall",
get_score = function(self)
if not self.touching_ground then
return 0.11, {self}
end
return 0
end
},
[3] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.5, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.3, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:bird_breed",
{
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.9, {self}
return 0.4, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local puncher = self._target
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._target = nil
return 0
end
}
},
activate_func = function(self)
@ -141,6 +167,10 @@ creatura.register_mob("animalia:chicken", {
animalia.head_tracking(self, 0.75, 0.75)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self.fall_start then
self:set_gravity(-4.9)
self:animate("fall")
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
@ -158,8 +188,7 @@ creatura.register_mob("animalia:chicken", {
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)
self._target = puncher
end
})

View file

@ -2,10 +2,12 @@
-- Cow --
---------
local random = math.random
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
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
@ -51,11 +53,12 @@ creatura.register_mob("animalia:cow", {
"animalia_cow_4.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 = 60, frame_blend = 0.3, loop = true},
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 61, y = 79}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 61, y = 79}, speed = 30, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
@ -82,77 +85,85 @@ creatura.register_mob("animalia:cow", {
},
follow = follows,
consumable_nodes = {
{
name = "default:dirt_with_grass",
replacement = "default:dirt"
},
{
name = "default:dry_dirt_with_dry_grass",
replacement = "default:dry_dirt"
}
["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
},
head_data = {
offset = {x = 0, y = 0.5, z = 0},
pitch_correction = -45,
offset = {x = 0, y = 0.7, z = 0.0},
pitch_correction = -65,
pivot_h = 0.75,
pivot_v = 1
},
-- Function
utility_stack = {
[1] = {
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:eat_from_turf",
{
utility = "animalia:eat_turf",
step_delay = 0.25,
get_score = function(self)
if math.random(25) < 2 then
return 0.1, {self}
if random(64) < 2 then
return 0.2, {self}
end
return 0
end
},
[3] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.3, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.4, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:mammal_breed",
{
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.9, {self}
return 0.5, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local puncher = self._target
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._target = nil
return 0
end
}
},
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self.gotten = self:recall("gotten") or false
self.collected = self:recall("collected") or false
end,
step_func = function(self)
animalia.step_timers(self)
@ -181,7 +192,7 @@ creatura.register_mob("animalia:cow", {
return
end
if self.gotten then
if self.collected then
minetest.chat_send_player(name, "This Cow has already been milked.")
return
end
@ -199,15 +210,14 @@ creatura.register_mob("animalia:cow", {
minetest.add_item(pos, {name = "animalia:bucket_milk"})
end
self.gotten = self:memorize("gotten", true)
self.collected = self:memorize("collected", true)
return
end
animalia.add_libri_page(self, clicker, {name = "cow", form = "pg_cow;Cows"})
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)
self._target = puncher
end
})

View file

@ -4,7 +4,9 @@
local random = math.random
local vec_add = vector.add
local vec_dist = vector.distance
local vec_sub = vector.subtract
creatura.register_mob("animalia:frog", {
-- Stats
@ -16,9 +18,10 @@ creatura.register_mob("animalia:frog", {
despawn_after = 2500,
-- Entity Physics
stepheight = 1.1,
max_fall = 100,
max_fall = 0,
turn_rate = 10,
bouyancy_multiplier = 0,
hydrodynamics_multiplier = 0.3,
-- Visuals
mesh = "animalia_frog.b3d",
hitbox = {
@ -37,9 +40,11 @@ creatura.register_mob("animalia:frog", {
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}
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
step_delay = 0.25,
makes_footstep_sound = true,
catch_with_net = true,
catch_with_lasso = true,
@ -64,81 +69,91 @@ creatura.register_mob("animalia:frog", {
},
-- Function
utility_stack = {
[1] = {
{
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self}
end
},
[2] = {
utility = "animalia:wander_water_surface",
{
utility = "animalia:aquatic_wander",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.11, {self}
return 0.2, {self}
end
return 0
end
},
[3] = {
utility = "animalia:eat_bug_nodes",
{
utility = "animalia:eat_bug",
get_score = function(self)
local pos = self.object:get_pos()
if math.random(12) * 0.01 then
local food = minetest.find_nodes_in_area(vector.subtract(pos, 1.5), vector.add(pos, 1.5), self.follow)
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.2, {self}
return 0.3, {self, food[1]}
end
end
return 0
end
},
[4] = {
utility = "animalia:flop",
get_score = function(self)
if not self.in_liquid
and self.growth_scale <= 0.6 then
return 1
end
return 0
end
},
[5] = {
utility = "animalia:breed_water_surface",
{
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
return 1, {self}
end
return 0
end
},
[6] = {
utility = "animalia:flee_from_player",
{
utility = "animalia:flop",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then return 0 end
local player = creatura.get_nearby_player(self)
if player
and player:get_player_name() then
local trust = self.trust[player:get_player_name()] or 0
self._nearby_player = player -- stored to memory to avoid calling get_nearby_player again
return (10 - (vec_dist(self.object:get_pos(), player:get_pos()) + trust)) * 0.1, {self, player}
if not self.in_liquid
and self.growth_scale <= 0.6 then
return 1, {self}
end
return 0
end
},
[7] = {
utility = "animalia:flee_to_water",
{
utility = "animalia:flee_from_target",
get_score = function(self)
if self.in_liquid then return 0 end
local pos = self.object:get_pos()
local water = minetest.find_nodes_in_area(vector.subtract(pos, 1.5), vector.add(pos, 1.5), {"default:water_source"})
if not pos then return end
local target = 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._nearby_player
if player
and player:get_player_name() then
local trust = self.trust[player:get_player_name()] or 0
return (10 - (vec_dist(self.object:get_pos(), player:get_pos()) + trust)) * 0.1, {self, player}
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
@ -177,14 +192,7 @@ creatura.register_mob("animalia:frog", {
end,
on_rightclick = function(self, clicker)
if animalia.feed(self, clicker, false, true) then
local name = clicker:get_player_name()
if self.trust[name] then
self.trust[name] = self.trust[name] + 1
else
self.trust[name] = 1
end
if self.trust[name] > 5 then self.trust[name] = 5 end
self:memorize("trust", self.trust)
animalia.add_trust(self, clicker, 1)
return
end
if animalia.set_nametag(self, clicker) then

View file

@ -7,7 +7,7 @@ local random = math.random
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
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
@ -16,42 +16,59 @@ minetest.register_on_mods_loaded(function()
end
end)
local function set_pattern(self)
local types = {
"spots",
"patches"
local patterns = {
"animalia_horse_pattern_1.png",
"animalia_horse_pattern_2.png",
"animalia_horse_pattern_3.png"
}
local avlbl_colors = {
[1] = {
"animalia_horse_2.png",
"animalia_horse_3.png",
"animalia_horse_6.png"
},
[2] = {
"animalia_horse_1.png",
"animalia_horse_6.png"
},
[3] = {
"animalia_horse_2.png",
"animalia_horse_1.png"
},
[4] = {
"animalia_horse_2.png",
"animalia_horse_1.png"
},
[5] = {
"animalia_horse_2.png",
"animalia_horse_1.png"
},
[6] = {
"animalia_horse_2.png",
"animalia_horse_1.png"
}
if self:recall("pattern")
and not self:recall("pattern"):find("better_fauna") then
local pattern = self:recall("pattern")
local texture = self.object:get_properties().textures[1]
self.object:set_properties({
textures = {texture .. "^" .. pattern}
})
else
local type = types[random(#types)]
local overlay = "(animalia_horse_".. type ..".png)"
if type == "patches" then
local colors = {
"brown",
"white"
}
if self.texture_no < 1 then
table.insert(colors, "black")
else
table.remove(colors, 1)
end
overlay = "(animalia_horse_".. colors[random(#colors)] .."_patches.png)"
}
local function set_pattern(self)
local pattern_no = self:recall("pattern_no")
if pattern_no and pattern_no < 1 then return end
if not pattern_no then
if random(3) < 2 then
pattern_no = self:memorize("pattern_no", random(#patterns))
else
self:memorize("pattern_no", 0)
return
end
if random(100) > 50 then
overlay = "transparency.png"
end
local texture = self.object:get_properties().textures[1]
self.object:set_properties({
textures = {texture .. "^" .. overlay}
})
self:memorize("pattern", overlay)
end
end
local colors = avlbl_colors[self.texture_no]
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]
self.object:set_properties({
textures = {texture .. "^" .. pattern}
})
end
creatura.register_mob("animalia:horse", {
@ -82,14 +99,16 @@ creatura.register_mob("animalia:horse", {
"animalia_horse_6.png"
},
animations = {
stand = {range = {x = 1, y = 60}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 70, y = 110}, speed = 30, frame_blend = 0.3, loop = true},
run = {range = {x = 120, y = 140}, speed = 30, frame_blend = 0.3, loop = true},
rear = {range = {x = 150, y = 180}, speed = 27, frame_blend = 0.2, loop = false},
rear_constant = {range = {x = 160, y = 170}, speed = 20, frame_blend = 0.3, loop = true},
eat = {range = {x = 190, y = 220}, speed = 20, frame_blend = 0.3, loop = false}
stand = {range = {x = 1, y = 59}, speed = 10, frame_blend = 0.3, loop = true},
walk = {range = {x = 61, y = 79}, speed = 20, frame_blend = 0.3, loop = true},
run = {range = {x = 81, y = 99}, speed = 30, frame_blend = 0.3, loop = true},
punch_aoe = {range = {x = 101, y = 119}, speed = 30, frame_blend = 0.2, loop = false},
rear = {range = {x = 121, y = 140}, speed = 20, frame_blend = 0.2, loop = false},
rear_constant = {range = {x = 121, y = 140}, speed = 20, frame_blend = 0.3, loop = false},
eat = {range = {x = 141, y = 160}, speed = 20, frame_blend = 0.3, loop = false}
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
@ -116,71 +135,101 @@ creatura.register_mob("animalia:horse", {
},
follow = follows,
consumable_nodes = {
{
name = "default:dirt_with_grass",
replacement = "default:dirt"
},
{
name = "default:dry_dirt_with_dry_grass",
replacement = "default:dry_dirt"
}
["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
},
head_data = {
bone = "Neck.CTRL",
offset = {x = 0, y = 1.2, z = 0.15},
pitch_correction = 45,
offset = {x = 0, y = 1.45, z = 0.0},
pitch_correction = 25,
pivot_h = 1,
pivot_v = 1.5
},
-- Function
wander_action = animalia.action_move_flock,
utility_stack = {
[1] = {
utility = "animalia:boid_wander",
{
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:eat_from_turf",
{
utility = "animalia:eat_turf",
step_delay = 0.25,
get_score = function(self)
return math.random(11) * 0.01, {self}
if random(64) < 2 then
return 0.2, {self}
end
return 0
end
},
[3] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.95, {self}
return 0.3, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.4, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:horse_breed",
{
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.9, {self}
return 0.5, {self}
end
return 0
end
},
[6] = {
utility = "animalia:mount",
{
utility = "animalia:flee_from_target_defend",
get_score = function(self)
if self.rider
and self.saddled then
return 1, {self, self.rider}
local puncher = self._puncher
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._puncher = nil
return 0
end
},
{
utility = "animalia:tame_horse",
get_score = function(self)
local rider = not self.owner and self.rider
if rider
and rider:get_pos() then
return 0.7, {self}
end
return 0
end
},
{
utility = "animalia:mount_horse",
get_score = function(self)
local owner = self.owner and minetest.get_player_by_name(self.owner)
local rider = owner == self.rider and self.rider
if rider
and rider:get_pos() then
return 0.8, {self, rider}
end
return 0
end
@ -219,43 +268,6 @@ creatura.register_mob("animalia:horse", {
animalia.head_tracking(self)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self.breaking
and self:timer(1) then
local pos = self:get_center_pos()
if not minetest.get_player_by_name(self.breaker) then
self.breaking = nil
self.breaker = nil
else
local yaw = self.object:get_yaw()
local yaw2 = minetest.get_player_by_name(self.breaker):get_look_horizontal()
if math.abs(yaw - yaw2) > 5.8
or math.abs(yaw - yaw2) < 0.5 then
self.breaking_progress = self.breaking_progress + 1
else
self.breaking_progress = self.breaking_progress - 1
end
self:initiate_utility("animalia:horse_breaking", self)
if self.breaking_progress < -5
or minetest.get_player_by_name(self.breaker):get_player_control().sneak then
animalia.mount(self, minetest.get_player_by_name(self.breaker))
creatura.action_idle(self, 0.5, "rear")
self.breaking = nil
self.breaker = nil
self.breaking_progress = nil
elseif self.breaking_progress > 5 then
animalia.mount(self, minetest.get_player_by_name(self.breaker))
self.owner = self:memorize("owner", self.breaker)
animalia.protect_from_despawn(self)
self.breaking = nil
self.breaker = nil
self.breaking_progress = nil
local prt_pos = vector.new(pos.x, pos.y + 2, pos.z)
local minppos = vector.add(prt_pos, 1)
local maxppos = vector.subtract(prt_pos, 1)
animalia.particle_spawner(prt_pos, "creatura_particle_green.png", "float", minppos, maxppos)
end
end
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
@ -275,7 +287,7 @@ creatura.register_mob("animalia:horse", {
and self.owner == clicker:get_player_name() then
if self.saddled
and tool_name == "" then
animalia.mount(self, clicker, {rot = {x = -60, y = 180, z = 0}, pos = {x = 0, y = 1.1, z = 0.5}})
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)
@ -293,16 +305,14 @@ creatura.register_mob("animalia:horse", {
elseif not self.owner
and tool_name == "" then
animalia.mount(self, clicker, {rot = {x = -60, y = 180, z = 0}, pos = {x = 0, y = 1.1, z = 0.5}})
self.breaking = true
self.breaker = clicker:get_player_name()
self.breaking_progress = 0
end
animalia.add_libri_page(self, clicker, {name = "horse", form = "pg_horse;Horses"})
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:boid_flee_from_player", self, puncher, true)
self:set_utility_score(1)
on_punch = function(self, puncher, ...)
if self.rider and puncher == self.rider then return end
creatura.basic_punch_func(self, puncher, ...)
if self.hp < 0 then return end
self._puncher = puncher
end
})

View file

@ -5,7 +5,7 @@
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
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
@ -64,6 +64,7 @@ creatura.register_mob("animalia:pig", {
run = {range = {x = 1, y = 20}, speed = 45, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
consumable_nodes = destroyable_crops,
birth_count = 2,
catch_with_net = true,
@ -93,24 +94,27 @@ creatura.register_mob("animalia:pig", {
utility_stack = {
[1] = {
utility = "animalia:wander",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
end
},
[2] = {
utility = "animalia:eat_from_turf",
step_delay = 0.25,
get_score = function(self)
if math.random(25) < 2 then
return 0.1, {self}
return 0.2, {self}
end
return 0
end
},
[3] = {
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.3, {self}
end
return 0
end
@ -118,24 +122,23 @@ creatura.register_mob("animalia:pig", {
[4] = {
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.4, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:mammal_breed",
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.9, {self}
return 0.5, {self}
end
return 0
end
@ -166,8 +169,7 @@ creatura.register_mob("animalia:pig", {
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)
self._target = puncher
end
})

View file

@ -5,7 +5,7 @@
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
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
@ -43,6 +43,7 @@ creatura.register_mob("animalia:reindeer", {
run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
drops = {
@ -68,54 +69,68 @@ creatura.register_mob("animalia:reindeer", {
},
-- Function
utility_stack = {
[1] = {
utility = "animalia:boid_wander",
{
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:eat_from_turf",
{
utility = "animalia:eat_turf",
step_delay = 0.25,
get_score = function(self)
if math.random(25) < 2 then
return 0.1, {self}
if random(64) < 2 then
return 0.2, {self}
end
return 0
end
},
[3] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.3, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.4, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:mammal_breed",
{
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.9, {self}
return 0.5, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local puncher = self._target
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._target = nil
return 0
end
}
},
activate_func = function(self)
@ -144,8 +159,7 @@ creatura.register_mob("animalia:reindeer", {
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:boid_flee_from_player", self, puncher, true)
self:set_utility_score(1)
self._target = puncher
end
})

View file

@ -2,10 +2,12 @@
-- Sheep --
-----------
local random = math.random
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
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
@ -69,6 +71,7 @@ creatura.register_mob("animalia:sheep", {
run = {range = {x = 70, y = 110}, speed = 50, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
@ -94,14 +97,8 @@ creatura.register_mob("animalia:sheep", {
},
follow = follows,
consumable_nodes = {
{
name = "default:dirt_with_grass",
replacement = "default:dirt"
},
{
name = "default:dry_dirt_with_dry_grass",
replacement = "default:dry_dirt"
}
["default:dirt_with_grass"] = "default:dirt",
["default:dry_dirt_with_dry_grass"] = "default:dry_dirt"
},
head_data = {
offset = {x = 0, y = 0.41, z = 0},
@ -111,67 +108,83 @@ creatura.register_mob("animalia:sheep", {
},
-- Function
utility_stack = {
[1] = {
utility = "animalia:wander",
{
utility = "animalia:wander_group",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:eat_from_turf",
{
utility = "animalia:eat_turf",
step_delay = 0.25,
get_score = function(self)
if math.random(25) < 2 then
return 0.1, {self}
if random(64) < 2 then
return 0.2, {self}
end
return 0
end
},
[3] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.3, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
return 0.4, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.4, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:mammal_breed",
{
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.9, {self}
return 0.5, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local puncher = self._target
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._target = nil
return 0
end
}
},
activate_func = function(self)
self.gotten = self:recall("gotten") or false
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.gotten then
and not self.collected then
self.object:set_properties({
textures = {"animalia_sheep.png^(animalia_sheep_wool.png^[colorize:" .. self.dye_hex .. ")"},
})
end
if self.gotten then
if self.collected then
self.object:set_properties({
textures = {"animalia_sheep.png"},
})
@ -202,7 +215,7 @@ creatura.register_mob("animalia:sheep", {
local tool = clicker:get_wielded_item()
local tool_name = tool:get_name()
if tool_name == "animalia:shears"
and not self.gotten
and not self.collected
and self.growth_scale > 0.9 then
if not minetest.get_modpath("wool") then
return
@ -213,7 +226,7 @@ creatura.register_mob("animalia:sheep", {
ItemStack( "wool:" .. self.dye_color .. " " .. math.random(1, 3) )
)
self.gotten = self:memorize("gotten", true)
self.collected = self:memorize("collected", true)
self.dye_color = self:memorize("dye_color", "white")
self.dye_hex = self:memorize("dye_hex", "#abababc000")
@ -227,9 +240,9 @@ creatura.register_mob("animalia:sheep", {
end
for _, color in ipairs(palette) do
if tool_name:find("dye:")
and not self.gotten
and not self.collected
and self.growth_scale > 0.9 then
local dye = string.split(tool_name, ":")[2]
local dye = tool_name:split(":")[2]
if color[1] == dye then
self.dye_color = self:memorize("dye_color", color[1])
@ -256,9 +269,8 @@ creatura.register_mob("animalia:sheep", {
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:boid_flee_from_player", self, puncher, true)
self:set_utility_score(1)
self._target = puncher
end
})
creatura.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b")
creatura.register_spawn_egg("animalia:sheep", "f4e6cf", "e1ca9b")

View file

@ -12,7 +12,7 @@ creatura.register_mob("animalia:tropical_fish", {
despawn_after = 2500,
-- Entity Physics
stepheight = 0.1,
max_fall = 8,
max_fall = 0,
turn_rate = 8,
boid_seperation = 0.3,
bouyancy_multiplier = 0,
@ -33,19 +33,22 @@ creatura.register_mob("animalia:tropical_fish", {
flop = {range = {x = 30, y = 40}, speed = 20, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = false,
makes_footstep_sound = false,
-- Function
utility_stack = {
{
utility = "animalia:schooling",
utility = "animalia:aquatic_wander_school",
step_delay = 0.25,
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)

View file

@ -5,7 +5,7 @@
local follows = {}
minetest.register_on_mods_loaded(function()
for name, def in pairs(minetest.registered_items) do
for name in pairs(minetest.registered_items) do
if name:match(":seed_")
or name:match("_seed") then
table.insert(follows, name)
@ -41,6 +41,7 @@ creatura.register_mob("animalia:turkey", {
fall = {range = {x = 70, y = 90}, speed = 30, frame_blend = 0.3, loop = true},
},
-- Misc
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
sounds = {
@ -72,55 +73,78 @@ creatura.register_mob("animalia:turkey", {
pivot_v = 0.65
},
-- 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,
utility_stack = {
[1] = {
utility = "animalia:wander",
{
utility = "animalia:wander_group",
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
utility = "animalia:resist_fall",
get_score = function(self)
if not self.touching_ground then
return 0.11, {self}
end
return 0
end
},
[3] = {
utility = "animalia:swim_to_land",
{
utility = "animalia:swim_to_Land",
get_score = function(self)
if self.in_liquid then
return 1, {self}
return 0.5, {self}
end
return 0
end
},
[4] = {
{
utility = "animalia:follow_player",
get_score = function(self)
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.8, {self, self.lasso_origin, true}
end
local player = creatura.get_nearby_player(self)
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
local force = lasso and lasso ~= false
local player = (force and lasso) or creatura.get_nearby_player(self)
if player
and self:follow_wielded_item(player) then
return 0.8, {self, player}
return 0.3, {self, player}
end
return 0
end
},
[5] = {
utility = "animalia:bird_breed",
{
utility = "animalia:breed",
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name) then
return 0.9, {self}
return 0.4, {self}
end
return 0
end
},
{
utility = "animalia:flee_from_target",
get_score = function(self)
local puncher = self._target
if puncher
and puncher:get_pos() then
return 0.6, {self, puncher}
end
self._target = nil
return 0
end
}
},
activate_func = function(self)
@ -132,6 +156,10 @@ creatura.register_mob("animalia:turkey", {
animalia.head_tracking(self, 0.75, 0.75)
animalia.do_growth(self, 60)
animalia.update_lasso_effects(self)
if self.fall_start then
self:set_gravity(-4.9)
self:animate("fall")
end
end,
death_func = function(self)
if self:get_utility() ~= "animalia:die" then
@ -149,8 +177,7 @@ creatura.register_mob("animalia:turkey", {
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)
self._target = puncher
end
})

View file

@ -2,7 +2,20 @@
-- Wolf --
----------
local vec_dist = vector.distance
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",
@ -40,6 +53,7 @@ creatura.register_mob("animalia:wolf", {
despawn_after = 2000,
-- Entity Physics
stepheight = 1.1,
max_fall = 3,
-- Visuals
mesh = "animalia_wolf.b3d",
hitbox = {
@ -47,117 +61,91 @@ creatura.register_mob("animalia:wolf", {
height = 0.7
},
visual_size = {x = 9, y = 9},
textures = {"animalia_wolf.png"},
textures = {
"animalia_wolf_1.png",
"animalia_wolf_2.png",
"animalia_wolf_3.png",
"animalia_wolf_4.png"
},
animations = {
stand = {range = {x = 30, y = 49}, speed = 10, frame_blend = 0.3, loop = true},
sit = {range = {x = 60, y = 90}, speed = 20, 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},
leap = {range = {x = 100, y = 100}, speed = 1, frame_blend = 0.15, loop = false}
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
step_delay = 0.25,
catch_with_net = true,
catch_with_lasso = true,
assist_owner = true,
follow = follow,
head_data = {
offset = {x = 0, y = 0.22, z = 0},
pitch_correction = -25,
offset = {x = 0, y = 0.33, z = 0},
pitch_correction = -67,
pivot_h = 0.65,
pivot_v = 0.65
},
-- Function
utility_stack = {
[1] = {
utility = "animalia:skittish_boid_wander",
{
utility = "animalia:wander_skittish",
step_delay = 0.25,
get_score = function(self)
return 0.1, {self, true}
return 0.1, {self}
end
},
[2] = {
{
utility = "animalia:swim_to_land",
step_delay = 0.25,
get_score = function(self)
if self.in_liquid then
return 0.9, {self}
return 0.3, {self}
end
return 0
end
},
[3] = {
utility = "animalia:attack",
{
utility = "animalia:attack_target",
get_score = function(self)
local target = creatura.get_nearby_entity(self, "animalia:sheep")
local player = self._nearby_player
local is_attacking = self:get_utility() == "animalia:attack"
if player
and player:get_player_name() then
if is_value_in_table(self.enemies, player:get_player_name()) then
local nearby_players = creatura.get_nearby_players(self)
local nearby_allies = creatura.get_nearby_entities(self, self.name)
if #nearby_players < #nearby_allies then
target = player
end
end
end
if target then
if is_attacking
and self._utility_data.args[2]
and self._utility_data.args[2] == target then
return 0
end
return 0.85, {self, target}
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
},
[4] = {
utility = "animalia:flee_from_player",
{
utility = "animalia:stay",
step_delay = 0.25,
get_score = function(self)
local player = self._nearby_player
if player
and player:get_player_name() then
if is_value_in_table(self.enemies, player:get_player_name()) then
local nearby_players = creatura.get_nearby_players(self)
local nearby_allies = creatura.get_nearby_entities(self, self.name)
if #nearby_players >= #nearby_allies then
return 0.86, {self, player}
end
end
local order = self.order or "wander"
if order == "sit" then
return 0.5, {self}
end
return 0
end
},
[5] = {
utility = "animalia:sit",
get_score = function(self)
if self.order == "sit" then
return 0.8, {self}
end
return 0
end
},
[6] = {
{
utility = "animalia:follow_player",
get_score = function(self)
local trust = 0
local player = self._nearby_player
if self.lasso_origin
and type(self.lasso_origin) == "userdata" then
return 0.7, {self, self.lasso_origin, true}
elseif player
and self:follow_wielded_item(player) then
return 0.7, {self, player}
end
if self.order == "follow"
and self.owner
and minetest.get_player_by_name(self.owner) then
return 1, {self, minetest.get_player_by_name(self.owner), true}
local lasso = type(self.lasso_origin or {}) == "userdata" and self.lasso_origin
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
},
[7] = {
utility = "animalia:mammal_breed",
{
utility = "animalia:breed",
step_delay = 0.25,
get_score = function(self)
if self.breeding
and animalia.get_nearby_mate(self, self.name) then
@ -170,7 +158,6 @@ creatura.register_mob("animalia:wolf", {
activate_func = function(self)
animalia.initialize_api(self)
animalia.initialize_lasso(self)
self._path = {}
self.order = self:recall("order") or "wander"
self.owner = self:recall("owner") or nil
self.enemies = self:recall("enemies") or {}
@ -194,10 +181,9 @@ creatura.register_mob("animalia:wolf", {
end,
on_rightclick = function(self, clicker)
if not clicker:is_player() then return end
local name = clicker:get_player_name()
local passive = true
if is_value_in_table(self.enemies, clicker:get_player_name()) then
passive = false
end
if is_value_in_table(self.enemies, name) then passive = false end
if animalia.feed(self, clicker, passive, passive) then
return
end
@ -205,21 +191,21 @@ creatura.register_mob("animalia:wolf", {
return
end
if self.owner
and clicker:get_player_name() == self.owner
and name == self.owner
and clicker:get_player_control().sneak then
local order = self.order
if order == "wander" then
minetest.chat_send_player(clicker:get_player_name(), "Wolf is following")
minetest.chat_send_player(name, "Wolf is following")
self.order = "follow"
self:initiate_utility("animalia:follow_player", self, clicker, true)
self:set_utility_score(1)
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(name, "Wolf is sitting")
self.order = "sit"
self:initiate_utility("animalia:sit", self)
self:set_utility_score(0.8)
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(name, "Wolf is wandering")
self.order = "wander"
self:set_utility_score(0)
end
@ -229,24 +215,24 @@ creatura.register_mob("animalia:wolf", {
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)
if puncher:is_player() then
local name = puncher:is_player() and puncher:get_player_name()
if name then
if self.owner
and puncher:get_player_name() == self.owner then
and name == self.owner then
return
elseif not is_value_in_table(self.enemies, puncher:get_player_name()) then
table.insert(self.enemies, puncher:get_player_name())
elseif not is_value_in_table(self.enemies, name) then
table.insert(self.enemies, name)
if #self.enemies > 15 then
table.remove(self.enemies, 1)
end
self.enemies = self:memorize("enemies", self.enemies)
else
table.remove(self.enemies, 1)
table.insert(self.enemies, puncher:get_player_name())
table.insert(self.enemies, name)
self.enemies = self:memorize("enemies", self.enemies)
end
end
self:initiate_utility("animalia:attack", self, puncher, true)
self:set_utility_score(1)
self._target = puncher
end,
deactivate_func = function(self)
if self.owner then