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
|
|
|
|
|
2022-02-13 21:40:12 +01:00
|
|
|
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-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-05-28 00:06:29 +02:00
|
|
|
mcl_mobs:set_animation(self, "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 then
|
|
|
|
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
|
|
|
|
2022-05-25 14:44:49 +02:00
|
|
|
mcl_mobs:register_mob("mobs_mc:parrot", {
|
2021-04-25 17:30:15 +02:00
|
|
|
description = S("Parrot"),
|
2017-07-05 03:15:46 +02:00
|
|
|
type = "npc",
|
2020-04-11 02:46:03 +02:00
|
|
|
spawn_class = "passive",
|
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-02-13 21:40:12 +01:00
|
|
|
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,
|
2020-12-05 03:21:39 +01:00
|
|
|
fly_speed = 50,
|
2022-05-22 19:46:10 +02:00
|
|
|
stand_start = 0,
|
|
|
|
stand_end = 0,
|
2020-12-05 03:21:39 +01:00
|
|
|
fly_start = 30,
|
|
|
|
fly_end = 45,
|
2022-05-22 19:46:10 +02:00
|
|
|
walk_start = 0,
|
|
|
|
walk_end = 20,
|
2020-12-05 03:21:39 +01:00
|
|
|
-- 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,
|
2020-12-05 14:48:58 +01:00
|
|
|
makes_footstep_sound = false,
|
2020-12-05 03:21:39 +01:00
|
|
|
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-05-28 00:06:29 +02:00
|
|
|
if mcl_mobs:feed_tame(self, 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-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
|
|
|
|
2021-04-07 18:47:40 +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",
|
2021-04-08 14:12:43 +02:00
|
|
|
"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,
|
|
|
|
30000,
|
|
|
|
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
|
2022-05-25 14:44:49 +02:00
|
|
|
mcl_mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)
|