VoxeLibre/mods/ENTITIES/mobs_mc/parrot.lua

244 lines
6.3 KiB
Lua
Raw Normal View History

2017-07-05 03:15:46 +02:00
--MCmobs v0.4
--maikerumine
--made for MC like Survival game
--License for code WTFPL and otherwise stated in readmes
local S = minetest.get_translator("mobs_mc")
2017-07-05 03:15:46 +02:00
--###################
--################### PARROT
--###################
2022-05-22 14:41:46 +02:00
local shoulders = {
2022-05-23 00:09:38 +02:00
left = vector.new(-3.75,10.5,0),
right = vector.new(3.75,10.5,0)
2022-05-22 14:41:46 +02:00
}
2017-07-05 03:15:46 +02:00
2022-08-17 22:17:33 +02:00
local function table_get_rand(tbl)
local keys = {}
for k in pairs(tbl) do
table.insert(keys, k)
end
return tbl[keys[math.random(#keys)]]
end
2022-07-17 23:34:39 +02:00
local function get_random_mob_sound()
local t = table.copy(minetest.registered_entities)
table.shuffle(t)
for _,e in pairs(t) do
2022-08-17 22:17:33 +02:00
if e.is_mob and e.sounds and #e.sounds > 0 then
return table_get_rand(e.sounds)
2022-07-17 23:34:39 +02:00
end
end
return minetest.registered_entities["mobs_mc:parrot"].sounds.random
end
local function imitate_mob_sound(self,mob)
local snd = mob.sounds.random
if not snd or mob.name == "mobs_mc:parrot" or math.random(20) == 1 then
snd = get_random_mob_sound()
end
return minetest.sound_play(snd, {
pos = self.object:get_pos(),
gain = 1.0,
pitch = 2.5,
max_hear_distance = self.sounds and self.sounds.distance or 32
}, true)
end
local function check_mobimitate(self,dtime)
if not self._mobimitate_timer or self._mobimitate_timer > 30 then
self._mobimitate_timer = 0
for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),20)) do
2022-07-17 23:34:39 +02:00
local l = o:get_luaentity()
if l and l.is_mob and l.name ~= "mobs_mc:parrot" then
imitate_mob_sound(self,l)
return
end
end
end
self._mobimitate_timer = self._mobimitate_timer + dtime
end
2022-05-22 14:41:46 +02:00
--find a free shoulder or return nil
local function get_shoulder(player)
2022-05-23 00:09:38 +02:00
local sh = "left"
2022-05-22 14:41:46 +02:00
for _,o in pairs(player:get_children()) do
local l = o:get_luaentity()
if l and l.name == "mobs_mc:parrot" then
local _,_,a = l.object:get_attach()
for _,s in pairs(shoulders) do
2022-05-23 00:09:38 +02:00
if a and vector.equals(a,s) then
if sh == "left" then
sh = "right"
else
return
end
end
2022-05-22 14:41:46 +02:00
end
end
end
2022-05-23 00:09:38 +02:00
return shoulders[sh]
2022-05-22 14:41:46 +02:00
end
local function perch(self,player)
if self.tamed and player:get_player_name() == self.owner and not self.object:get_attach() then
local shoulder = get_shoulder(player)
if not shoulder then return true end
self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true)
2022-11-09 06:06:59 +01:00
self:set_animation("stand")
2022-05-22 14:41:46 +02:00
end
end
2017-07-05 03:15:46 +02:00
2022-05-23 00:09:38 +02:00
local function check_perch(self,dtime)
if self.object:get_attach() then
for _,p in pairs(minetest.get_connected_players()) do
for _,o in pairs(p:get_children()) do
local l = o:get_luaentity()
if l and l.name == "mobs_mc:parrot" then
local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name
local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name
local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name
if ( n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0) and
not minetest.is_creative_enabled(p:get_player_name()) then
2022-05-23 00:09:38 +02:00
o:set_detach()
self.detach_timer = 0
return
end
end
end
end
elseif not self.detach_timer then
for _,p in pairs(minetest.get_connected_players()) do
if vector.distance(self.object:get_pos(),p:get_pos()) < 0.5 then
perch(self,p)
return
end
end
elseif self.detach_timer then
if self.detach_timer > 1 then
self.detach_timer = nil
else
self.detach_timer = self.detach_timer + dtime
end
end
end
2017-07-05 03:15:46 +02:00
mcl_mobs.register_mob("mobs_mc:parrot", {
2021-04-25 17:30:15 +02:00
description = S("Parrot"),
2022-09-01 22:12:25 +02:00
type = "animal",
2020-04-11 02:46:03 +02:00
spawn_class = "passive",
2022-09-01 22:12:25 +02:00
passive = true,
2017-07-05 03:15:46 +02:00
pathfinding = 1,
hp_min = 6,
hp_max = 6,
2020-12-06 15:46:42 +01:00
xp_min = 1,
xp_max = 3,
2022-10-07 04:08:47 +02:00
head_swivel = "head.control",
2024-11-11 17:29:07 +01:00
head_bone_position = vector.new( 0, 1.1, 0 ), -- for minetest <= 5.8
2022-10-07 04:08:47 +02:00
curiosity = 10,
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
2017-07-05 03:15:46 +02:00
visual = "mesh",
mesh = "mobs_mc_parrot.b3d",
textures = {{"mobs_mc_parrot_blue.png"},{"mobs_mc_parrot_green.png"},{"mobs_mc_parrot_grey.png"},{"mobs_mc_parrot_red_blue.png"},{"mobs_mc_parrot_yellow_blue.png"}},
visual_size = {x=3, y=3},
walk_velocity = 3,
run_velocity = 5,
2020-12-05 17:14:56 +01:00
sounds = {
random = "mobs_mc_parrot_random",
damage = {name="mobs_mc_parrot_hurt", gain=0.3},
death = {name="mobs_mc_parrot_death", gain=0.6},
2020-12-05 23:37:12 +01:00
eat = "mobs_mc_animal_eat_generic",
2020-12-05 17:14:56 +01:00
distance = 16,
},
2017-07-05 03:15:46 +02:00
drops = {
2022-05-25 23:25:15 +02:00
{name = "mcl_mobitems:feather",
2017-07-05 03:15:46 +02:00
chance = 1,
min = 1,
2020-12-23 17:41:42 +01:00
max = 2,
looting = "common",},
2017-07-05 03:15:46 +02:00
},
2022-05-25 23:25:15 +02:00
animation = {
2017-07-05 03:15:46 +02:00
stand_speed = 50,
walk_speed = 50,
fly_speed = 50,
stand_start = 0,
stand_end = 0,
fly_start = 30,
fly_end = 45,
walk_start = 0,
walk_end = 20,
-- TODO: actual walk animation
--walk_start = 0,
--walk_end = 20,
-- TODO: more unused animations between 45 and 130
2017-07-05 03:15:46 +02:00
},
fall_damage = 0,
fall_speed = -2.25,
attack_type = "dogfight",
floats = 1,
physical = true,
fly = true,
makes_footstep_sound = false,
fear_height = 0,
2017-07-05 03:15:46 +02:00
view_range = 16,
2022-05-25 23:25:15 +02:00
follow = {
"mcl_farming:wheat_seeds",
"mcl_farming:melon_seeds",
"mcl_farming:pumpkin_seeds",
"mcl_farming:beetroot_seeds",
},
2017-07-05 03:15:46 +02:00
on_rightclick = function(self, clicker)
if self._doomed then return end
local item = clicker:get_wielded_item()
-- Kill parrot if fed with cookie
2022-05-25 23:25:15 +02:00
if item:get_name() == "mcl_farming:cookie" then
2020-12-05 23:37:12 +01:00
minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true)
2017-07-05 03:15:46 +02:00
self.health = 0
-- Doomed to die
self._doomed = true
2020-07-10 16:08:40 +02:00
if not minetest.is_creative_enabled(clicker:get_player_name()) then
2017-07-05 03:15:46 +02:00
item:take_item()
clicker:set_wielded_item(item)
end
return
end
-- Feed to tame, but not breed
2022-11-09 04:57:48 +01:00
if self:feed_tame(clicker, 1, false, true) then return end
2022-05-22 14:41:46 +02:00
perch(self,clicker)
2017-07-05 03:15:46 +02:00
end,
2022-05-22 14:41:46 +02:00
do_custom = function(self,dtime)
2022-05-23 00:09:38 +02:00
check_perch(self,dtime)
2022-07-17 23:34:39 +02:00
check_mobimitate(self,dtime)
2022-05-23 19:59:59 +02:00
end,
do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later....
if self.object:get_attach() == puncher then
return false --return false explicitly here. mcl_mobs checks for that
2022-05-22 14:41:46 +02:00
end
2022-05-23 19:59:59 +02:00
end,
})
2022-05-22 14:41:46 +02:00
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
2022-05-25 14:44:49 +02:00
mcl_mobs:spawn_specific(
2021-04-08 13:39:18 +02:00
"mobs_mc:parrot",
2021-04-25 17:30:15 +02:00
"overworld",
"ground",
2021-04-08 13:39:18 +02:00
{
"Jungle",
"JungleEdgeM",
"JungleM",
"JungleEdge",
},
2021-04-25 17:30:15 +02:00
0,
minetest.LIGHT_MAX+1,
7,
400,
2021-04-25 17:30:15 +02:00
1,
2022-05-25 23:25:15 +02:00
mobs_mc.water_level+7,
mcl_vars.mg_overworld_max)
2017-07-05 03:15:46 +02:00
-- spawn eggs
mcl_mobs.register_egg("mobs_mc:parrot", S("Parrot"), "#0da70a", "#ff0000", 0)