From 14ec1aa014d593d3ef49acb1c35022e5e0d7ac12 Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 14:41:46 +0200 Subject: [PATCH 1/6] add basic parrot perching --- mods/ENTITIES/mobs_mc/parrot.lua | 57 ++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index f3e3723c88..a17838d106 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -8,7 +8,35 @@ local S = minetest.get_translator("mobs_mc") --################### --################### PARROT --################### +local shoulders = { + left = vector.new(-3.25,10.5,0), + right = vector.new(3.25,10.5,0) +} +--find a free shoulder or return nil +local function get_shoulder(player) + local sh = 0 + 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 + if a and vector.equals(a,s) then sh = sh + 1 end + end + end + end + if sh == 0 then return shoulders["left"] + elseif sh == 1 then return shoulders["right"] end +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) + mobs:set_animation(self, "stand") + end +end mcl_mobs:register_mob("mobs_mc:parrot", { @@ -89,13 +117,36 @@ mcl_mobs:register_mob("mobs_mc:parrot", { end -- Feed to tame, but not breed - if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end - if mcl_mobs:protect(self, clicker) then return end - if mcl_mobs:capture_mob(self, clicker, 0, 50, 80, false, nil) then return end + if mobs:feed_tame(self, clicker, 1, false, true) then return end + perch(self,clicker) end, + do_custom = function(self,dtime) + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(self.object:get_pos(),p:get_pos()) < 1 then + perch(self,p) + end + for _,o in pairs(p:get_children()) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:parrot" then + if minetest.get_node(vector.offset(p:get_pos(),0,-1,0)).name == "air" then + o:set_detach() + end + end + end + end + end }) +minetest.register_on_leaveplayer(function(p) + for _,o in pairs(p:get_children()) do + local l = o:get_luaentity() + if l and l.name == "mobs_mc:parrot" then + l.object:set_detach() + end + end +end) + -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i mcl_mobs:spawn_specific( "mobs_mc:parrot", From 86bc398a7932cbce49c2a077549a0341f5ffd981 Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 19:46:10 +0200 Subject: [PATCH 2/6] don't do flying animation while perching,fix anims --- mods/ENTITIES/mcl_mobs/api.lua | 62 ++++++++++++++++---------------- mods/ENTITIES/mobs_mc/parrot.lua | 8 ++--- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 6b2cff0e37..933634ccee 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -363,6 +363,35 @@ local remove_texture_mod = function(self, mod) self.object:set_texture_mod(full_mod) end +-- are we flying in what we are suppose to? (taikedz) +local flight_check = function(self) + + local nod = self.standing_in + local def = minetest.registered_nodes[nod] + + if not def then return false end -- nil check + + local fly_in + if type(self.fly_in) == "string" then + fly_in = { self.fly_in } + elseif type(self.fly_in) == "table" then + fly_in = self.fly_in + else + return false + end + + for _,checknode in pairs(fly_in) do + if nod == checknode then + return true + elseif checknode == "__airlike" or def.walkable == false and + (def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then + return true + end + end + + return false +end + -- set defined animation local set_animation = function(self, anim, fixed_frame) if not self.animation or not anim then @@ -372,6 +401,8 @@ local set_animation = function(self, anim, fixed_frame) return end + if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end + self.animation.current = self.animation.current or "" if (anim == self.animation.current @@ -513,37 +544,6 @@ local line_of_sight = function(self, pos1, pos2, stepsize) return false end - --- are we flying in what we are suppose to? (taikedz) -local flight_check = function(self) - - local nod = self.standing_in - local def = minetest.registered_nodes[nod] - - if not def then return false end -- nil check - - local fly_in - if type(self.fly_in) == "string" then - fly_in = { self.fly_in } - elseif type(self.fly_in) == "table" then - fly_in = self.fly_in - else - return false - end - - for _,checknode in pairs(fly_in) do - if nod == checknode then - return true - elseif checknode == "__airlike" and def.walkable == false and - (def.liquidtype == "none" or minetest.get_item_group(nod, "fake_liquid") == 1) then - return true - end - end - - return false -end - - -- custom particle effects local effect = function(pos, amount, texture, min_size, max_size, radius, gravity, glow, go_down) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index a17838d106..cf380e1c9c 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -73,12 +73,12 @@ mcl_mobs:register_mob("mobs_mc:parrot", { stand_speed = 50, walk_speed = 50, fly_speed = 50, - stand_start = 30, - stand_end = 45, + stand_start = 0, + stand_end = 0, fly_start = 30, fly_end = 45, - walk_start = 30, - walk_end = 45, + walk_start = 0, + walk_end = 20, -- TODO: actual walk animation --walk_start = 0, --walk_end = 20, From 3d13000599f9aa69847a79424f1bed36497e8d54 Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 19:47:53 +0200 Subject: [PATCH 3/6] tweak detaching behavior --- mods/ENTITIES/mobs_mc/parrot.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index cf380e1c9c..ee1a08de80 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -128,7 +128,10 @@ mcl_mobs:register_mob("mobs_mc:parrot", { for _,o in pairs(p:get_children()) do local l = o:get_luaentity() if l and l.name == "mobs_mc:parrot" then - if minetest.get_node(vector.offset(p:get_pos(),0,-1,0)).name == "air" 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() end end From e90e17e533d64a955e8a693a6b297def9b29f1ed Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 23 May 2022 00:09:38 +0200 Subject: [PATCH 4/6] clean up perch code, smoother behavior --- mods/ENTITIES/mobs_mc/parrot.lua | 67 +++++++++++++++++++++----------- 1 file changed, 45 insertions(+), 22 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index ee1a08de80..21930b2396 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -9,24 +9,30 @@ local S = minetest.get_translator("mobs_mc") --################### PARROT --################### local shoulders = { - left = vector.new(-3.25,10.5,0), - right = vector.new(3.25,10.5,0) + left = vector.new(-3.75,10.5,0), + right = vector.new(3.75,10.5,0) } --find a free shoulder or return nil local function get_shoulder(player) - local sh = 0 + local sh = "left" 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 - if a and vector.equals(a,s) then sh = sh + 1 end + if a and vector.equals(a,s) then + if sh == "left" then + sh = "right" + else + return + end + + end end end end - if sh == 0 then return shoulders["left"] - elseif sh == 1 then return shoulders["right"] end + return shoulders[sh] end local function perch(self,player) @@ -38,6 +44,38 @@ local function perch(self,player) end end +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 mcl_mobs:register_mob("mobs_mc:parrot", { description = S("Parrot"), @@ -121,22 +159,7 @@ mcl_mobs:register_mob("mobs_mc:parrot", { perch(self,clicker) end, do_custom = function(self,dtime) - for _,p in pairs(minetest.get_connected_players()) do - if vector.distance(self.object:get_pos(),p:get_pos()) < 1 then - perch(self,p) - end - 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() - end - end - end - end + check_perch(self,dtime) end }) From c0a9cb7020a1075809b3adabfd287f21bb2ad8ea Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 23 May 2022 19:59:59 +0200 Subject: [PATCH 5/6] don't hurt perched parrot on punch --- mods/ENTITIES/mobs_mc/parrot.lua | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 21930b2396..b4a91ba5b4 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -153,25 +153,19 @@ mcl_mobs:register_mob("mobs_mc:parrot", { end return end - -- Feed to tame, but not breed if mobs:feed_tame(self, clicker, 1, false, true) then return end perch(self,clicker) end, do_custom = function(self,dtime) check_perch(self,dtime) - end - -}) - -minetest.register_on_leaveplayer(function(p) - for _,o in pairs(p:get_children()) do - local l = o:get_luaentity() - if l and l.name == "mobs_mc:parrot" then - l.object:set_detach() + 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 end - end -end) + end, +}) -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i mcl_mobs:spawn_specific( From 7bc63d2882fa3123d817be54a471aef126b6e854 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 28 May 2022 00:06:29 +0200 Subject: [PATCH 6/6] fix mcl_mobs api_changes --- mods/ENTITIES/mobs_mc/parrot.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index b4a91ba5b4..84b3aaead7 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -40,7 +40,7 @@ local function perch(self,player) local shoulder = get_shoulder(player) if not shoulder then return true end self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true) - mobs:set_animation(self, "stand") + mcl_mobs:set_animation(self, "stand") end end @@ -154,7 +154,7 @@ mcl_mobs:register_mob("mobs_mc:parrot", { return end -- Feed to tame, but not breed - if mobs:feed_tame(self, clicker, 1, false, true) then return end + if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end perch(self,clicker) end, do_custom = function(self,dtime)