diff --git a/animals/crocodile.lua b/animals/crocodile.lua index b6b35ae..71d17a2 100644 --- a/animals/crocodile.lua +++ b/animals/crocodile.lua @@ -81,13 +81,13 @@ local function croc_brain(self) and not water_life.isinliquid(target) then local dist = water_life.dist2tgt(self,target) if dist < 10 then - water_life.hq_go2land(self,15,target) + water_life.hq_go2land(self,20,target) end end if food and mobkit.is_alive(food) and not water_life.isinliquid(food) then local dist = water_life.dist2tgt(self,food) if dist < 16 then - water_life.hq_go2land(self,15,food) + water_life.hq_go2land(self,20,food) end end end @@ -154,7 +154,7 @@ minetest.register_entity("water_life:croc",{ {name = "water_life:meat_raw", chance = 1, min = 1, max = 5,}, {name = "water_life:crocleather", chance = 2, min = 1, max = 2}, }, - attack={range=0.8,damage_groups={fleshy=7}}, + attack={range=1.1,damage_groups={fleshy=7}}, sounds = { attack={ {name = 'water_life_crocattack', diff --git a/animals/hippo.lua b/animals/hippo.lua new file mode 100644 index 0000000..2157529 --- /dev/null +++ b/animals/hippo.lua @@ -0,0 +1,158 @@ +local random = water_life.random +local abs = math.abs +local pi = math.pi +local floor = math.floor +local sqrt = math.sqrt +local max = math.max +local min = math.min +local pow = math.pow +local sign = math.sign +local rad = math.rad + +local function hippo_brain(self) + + local prty = mobkit.get_queue_priority(self) + + --die + if self.hp <= 0 then + mobkit.clear_queue_high(self) + water_life.handle_drops(self) + mobkit.hq_die(self) + return + end + + --chose between land and water + if mobkit.timer(self,10) then + local land = mobkit.recall(self,"landlife") + local water = mobkit.recall(self,"waterlife") + + if land and prty < 15 then + land = math.floor(os.time() - land) + if land > 30 and random(100) < land then + water_life.hq_go2water(self,15) + end + end + if water and prty < 15 then + water = math.floor(os.time() - water) + if water > 120 and random (1000) < water then + water_life.hq_go2land(self,15) + end + end + end + + --every other action check each second + if mobkit.timer(self,1) then + if not mobkit.recall(self,"landlife") and not mobkit.recall(self,"waterlife") then + mobkit.remember(self,"waterlife",os.time()) + end + if self.isinliquid and mobkit.recall(self,"landlife") then + mobkit.remember(self,"waterlife",os.time()) + mobkit.forget(self,"landlife") + end + if self.isonground and mobkit.recall(self,"waterlife") then + mobkit.remember(self,"landlife",os.time()) + mobkit.forget(self,"waterlife") + end + + local target = mobkit.get_nearby_player(self) + local aliveinwater = target and mobkit.is_alive(target) and water_life.isinliquid(target) + if target and mobkit.is_alive(target) and target:get_attach() == nil + and water_life.isinliquid(target) then + local dist = water_life.dist2tgt(self,target) + if dist and dist < 8 then + water_life.hq_water_attack(self,target,26,5,true) + end + end + + --on land + if self.isonground then + local rnd = random(1000) + if rnd < 30 then + mobkit.make_sound(self,"idle") + end + if target and mobkit.is_alive(target) then + local dist = water_life.dist2tgt(self,target) + if dist < self.view_range / 2 then + water_life.hq_hunt(self,24,target,7) + end + end + end + end + if mobkit.is_queue_empty_high(self) then + if self.isinliquid then + water_life.hq_aqua_roam(self,10,1,nil,false) + else + water_life.hq_slow_roam(self,12) + end + end +end + +minetest.register_entity("water_life:hippo",{ + physical = true, + stepheight = 1.1, + collide_with_objects = true, + collisionbox = {-0.49, 0, -0.49, 0.49, 1.99, 0.49}, + visual = "mesh", + mesh = "water_life_hippo.b3d", + textures = {"water_life_hippo.png"}, + visual_size = {x = 1.5, y = 1.5}, + static_save = true, + makes_footstep_sound = true, + on_step = mobkit.stepfunc, + on_activate = mobkit.actfunc, + get_staticdata = mobkit.statfunc, + springiness=0, + buoyancy = 0.98, + max_speed = 5, + jump_height = 1.49, + view_range = 16, + max_hp = 100, + timeout=300, + drops = { + {name = "default:diamond", chance = 5, min = 2, max = 6,}, + {name = "water_life:meat_raw", chance = 1, min = 4, max = 10,}, + }, + attack={range=0.8,damage_groups={fleshy=12}}, + sounds = { + attack={ + {name = 'water_life_hippo_angry1', + gain = water_life.soundadjust}, + {name = 'water_life_hippo_angry2', + gain = water_life.soundadjust} + }, + idle={ + {name = "water_life_hippo_idle1", + gain = water_life.soundadjust}, + {name = "water_life_hippo_idle2", + gain = water_life.soundadjust}, + {name = "water_life_hippo_idle3", + gain = water_life.soundadjust}, + {name = "water_life_hippo_idle4", + gain = water_life.soundadjust}, + {name = "water_life_hippo_idle5", + gain = water_life.soundadjust}, + } + }, + animation = { + def={range={x=0,y=100},speed=5,loop=true}, + stand={range={x=0,y=100},speed=1,loop=false}, + die={range={x=100,y=200},speed=1,loop=false}, + walk={range={x=300,y=400},speed=15,loop=true}, + swim={range={x=300,y=400},speed=30,loop=true}, + }, + + brainfunc = hippo_brain, + + on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir) + if mobkit.is_alive(self) then + local hvel = vector.multiply(vector.normalize({x=dir.x,y=0,z=dir.z}),4) + self.object:set_velocity({x=hvel.x,y=2,z=hvel.z}) + if water_life.bloody then water_life.spilltheblood(self.object) end + mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1) + if type(puncher)=='userdata' and puncher:is_player() then + mobkit.clear_queue_high(self) + water_life.hq_water_attack(self,puncher,20,6,true) + end + end + end, +}) diff --git a/animals/snake.lua b/animals/snake.lua index 0cd396b..2de8357 100644 --- a/animals/snake.lua +++ b/animals/snake.lua @@ -22,15 +22,13 @@ local function snake_brain(self) if land then land = math.floor(os.time() - land) if random(240,360) < land then - mobkit.clear_queue_high(self) - water_life.hq_go2water(self, 15) + water_life.hq_go2water(self, 5) end end if water then water = math.floor(os.time()-water) if random (60,120) < water then - mobkit.clear_queue_high(self) - water_life.hq_go2land(self, 25) + water_life.hq_go2land(self, 5) end end end @@ -64,9 +62,7 @@ local function snake_brain(self) -- snakes do not attack when in water end end - if self.isinliquid then - mobkit.clear_queue_high(self) - mobkit.clear_queue_low(self) + if self.isinliquid and prty < 21 then water_life.hq_aqua_roam(self, 21, 1, "swim") end if self.isonground then @@ -75,8 +71,6 @@ local function snake_brain(self) local pname = target:get_player_name() local dist = water_life.dist2tgt(self, target) if dist > 4 and dist < self.view_range and not action then - mobkit.clear_queue_high(self) - mobkit.clear_queue_low(self) water_life.hq_snake_warn(self, target, 30, 8) elseif dist < 5 or action == pname then mobkit.forget(self, "warned") diff --git a/api.lua b/api.lua index 300a7a9..d73fb42 100644 --- a/api.lua +++ b/api.lua @@ -189,19 +189,19 @@ function water_life.dist2tgt(self,tgt) local pos = mobkit.get_stand_pos(self) local tpos = tgt:get_pos() if (not tgt or not self) then - return 100 + return 100 else return vector.distance(pos,tpos) end end function water_life.dumbstep(self,height,tpos,speed_factor,idle_duration) - if height <= 0.001 then + if height <= 0.001 or self.isinliquid then mobkit.lq_turn2pos(self,tpos) water_life.lq_dumbwalk(self,tpos,speed_factor) else mobkit.lq_turn2pos(self,tpos) - water_life.lq_dumbjump(self,height) + mobkit.lq_dumbjump(self,height) end idle_duration = idle_duration or 6 mobkit.lq_idle(self,random(ceil(idle_duration*0.5),idle_duration)) @@ -615,6 +615,36 @@ function water_life.find_node_under_air(pos,radius,name) end end +-- recursively search for a water node with depth or return nil after stop tries +function water_life.get_pos_with_depth(start, radius, depth, stop, yaw, doNotUse) + local tgt = nil + radius = radius or 16 + depth = depth or 2 + stop = stop or radius + doNotUse = doNotUse or stop + + if not start or stop <= 0 then + return nil + end + if not yaw then + tgt = minetest.find_node_near(start, radius, {"group:water"}) + if not tgt then + return nil + end + yaw = minetest.dir_to_yaw(vector.direction(start, tgt)) + else + tgt = mobkit.pos_translate2d(start, yaw, 3) + end + local dep, type, surface = water_life.water_depth(tgt) + if (surface and (dep < depth or stop > doNotUse - 3)) then + return water_life.get_pos_with_depth(tgt, radius, depth, stop - 1, yaw, doNotUse) + elseif surface then + return tgt + else + return nil + end +end + -- function to find liquid surface and depth at that position returns depth or max, type of water node and surface position function water_life.water_depth(pos,max) local surface = {} @@ -704,25 +734,22 @@ function water_life.getLandPos(self, start) local target = nil local fpos = nil local pos = mobkit.get_stand_pos(self) + local radius = math.abs(self.collisionbox[5] - self.collisionbox[2]) + pos = mobkit.pos_shift(pos, {y = radius - 1}) - for i = start,359,15 do - local yaw = rad(i) - target = mobkit.pos_translate2d(pos,yaw,self.view_range) + for yaw = start,359,15 do + target = mobkit.pos_translate2d(pos, rad(yaw), self.view_range) fpos = water_life.find_collision(pos,target,false) if fpos then - target = mobkit.pos_translate2d(pos,yaw,fpos+0.5) - local node=minetest.get_node({x=target.x,y=target.y+1, + target = mobkit.pos_translate2d(pos, rad(yaw), fpos+0.5) + local node=minetest.get_node({x=target.x,y=target.y + 1, z=target.z}) - if node.name == "air" then + if node.name == "air" then return target - else - target = nil - end - else - target = nil + end end end - return target + return nil end function water_life.goto_next_waypoint(self,tpos) diff --git a/behaviors.lua b/behaviors.lua index 35a31b5..2f179c2 100644 --- a/behaviors.lua +++ b/behaviors.lua @@ -222,8 +222,6 @@ function water_life.lq_fly_pitch(self,lift,pitch,roll,acc,anim) mobkit.queue_low(self,func) end - - function water_life.lq_dumbjump(self,height,anim) anim = anim or 'stand' local jump = true @@ -245,7 +243,6 @@ function water_life.lq_dumbjump(self,height,anim) mobkit.queue_low(self,func) end - function water_life.lq_dumbwalk(self,dest,speed_factor) local timer = 3 -- failsafe speed_factor = speed_factor or 1 @@ -257,7 +254,7 @@ function water_life.lq_dumbwalk(self,dest,speed_factor) local pos = mobkit.get_stand_pos(self) local y = self.object:get_velocity().y local dir = vector.normalize(vector.direction({x=pos.x,y=0,z=pos.z}, - {x=dest.x,y=0,z=dest.z})) + {x=dest.x,y=0,z=dest.z})) dir = vector.multiply(dir,self.max_speed*speed_factor) mobkit.turn2yaw(self,minetest.dir_to_yaw(dir)) dir.y = y @@ -266,7 +263,6 @@ function water_life.lq_dumbwalk(self,dest,speed_factor) mobkit.queue_low(self,func) end - function water_life.lq_jumpattack(self,height,target,extra) local phase=1 local timer=0.5 @@ -463,12 +459,14 @@ end -- this is the same as mobkit's, but allows movement in shallow water -function water_life.hq_aqua_roam(self,prty,speed,anim) +function water_life.hq_aqua_roam(self,prty,speed,anim,shallow) if not anim then anim = "def" end + if shallow == nil then shallow = true end local tyaw = 0 local init = true local prvscanpos = {x=0,y=0,z=0} local center = self.object:get_pos() + local func = function(self) if init then mobkit.animate(self,anim) @@ -482,7 +480,7 @@ function water_life.hq_aqua_roam(self,prty,speed,anim) local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed)) if not vector.equals(prvscanpos,scanpos) then prvscanpos=scanpos - local nyaw,height = water_life.aqua_radar_dumb(pos,yaw,speed,false,true) + local nyaw,height = water_life.aqua_radar_dumb(pos,yaw,speed,false,shallow) if height and height > pos.y then local vel = self.object:get_velocity() vel.y = vel.y+1 @@ -510,7 +508,6 @@ function water_life.hq_aqua_roam(self,prty,speed,anim) mobkit.queue_high(self,func,prty) end - function water_life.hq_attack(self,prty,tgtobj) local func = function(self) if self.isinliquid then return true end @@ -557,7 +554,7 @@ end function water_life.hq_hunt(self, prty, tgtobj, lost, anim) if not lost then lost = self.view_range end - if random(100) < 20 then mobkit.make_sound(self,"attack") end + if water_life.random(100) < 33 then mobkit.make_sound(self,"attack") end local func = function(self) if not mobkit.is_alive(tgtobj) or not tgtobj then return true end @@ -616,27 +613,31 @@ end --find any water nearby and go into it function water_life.hq_go2water(self,prty,speed) local pos = mobkit.get_stand_pos(self) - local target = minetest.find_node_near(pos, self.view_range, {"group:water"}) - if not speed then speed = 0.1 end + local target = water_life.get_pos_with_depth(pos, self.view_range, 2, 100) + speed = speed or 0.1 + local dist = self.collisionbox[5] or 2 + dist = dist - (self.collisionbox[2] or 1) if not target then return true end + --water_life.temp_show(target, 5, 15) local func=function(self) - if self.isinliquid then - return true + if self.isinliquid and vector.distance(target, self.object:get_pos()) <= dist then + mobkit.clear_queue_high(self) + mobkit.clear_queue_low(self) + return true end - if mobkit.is_queue_empty_low(self) or self.isonground then - mobkit.dumbstep(self,0,target,speed,0) + if mobkit.is_queue_empty_low(self) then + water_life.dumbstep(self,0,target,speed,0) end end mobkit.queue_high(self,func,prty) end --- looks for a landing point on shore under air. tgt is optional --- and must be an object, so it will start searching yaw2tgt - 15 degrees +-- looks for a landing point on shore under air. tgt is object (optional) function water_life.hq_go2land(self,prty,tgt) - local init = false + local init = true local offset = 1 local target = nil local start = 1 @@ -648,40 +649,39 @@ function water_life.hq_go2land(self,prty,tgt) local func = function(self) local pos = mobkit.get_stand_pos(self) - if not init then + if init then target = water_life.getLandPos(self, start) - init = true + if not target then + return true + end + init = false end - if self.isonground then + local y=self.object:get_velocity().y + local pos2d = {x=pos.x,y=0,z=pos.z} + local dir=vector.normalize(vector.direction(pos2d,target)) + local yaw = minetest.dir_to_yaw(dir) + if mobkit.timer(self,1) then + if self.isonground and target and vector.distance(pos,target) < 1 then mobkit.clear_queue_low(self) mobkit.clear_queue_high(self) return true - end - if target then - local y=self.object:get_velocity().y - local pos2d = {x=pos.x,y=0,z=pos.z} - local dir=vector.normalize(vector.direction(pos2d,target)) - local yaw = minetest.dir_to_yaw(dir) - if mobkit.timer(self,1) then - local pos1 = mobkit.pos_shift(mobkit.pos_shift(pos, - {x=-dir.z*offset,z=dir.x*offset}),dir) - local h,l = mobkit.get_terrain_height(pos1) + end + local pos1 = mobkit.pos_shift(mobkit.pos_shift(pos, + {x=-dir.z*offset,z=dir.x*offset}),dir) + local h,l = mobkit.get_terrain_height(pos1) + if h and h > pos.y then + mobkit.lq_freejump(self) + else + local pos2 = mobkit.pos_shift(mobkit.pos_shift(pos, + {x=dir.z*offset,z=-dir.x*offset}),dir) + local h,l = mobkit.get_terrain_height(pos2) if h and h > pos.y then mobkit.lq_freejump(self) - else - local pos2 = mobkit.pos_shift(mobkit.pos_shift(pos, - {x=dir.z*offset,z=-dir.x*offset}),dir) - local h,l = mobkit.get_terrain_height(pos2) - if h and h > pos.y then - mobkit.lq_freejump(self) - end end - elseif mobkit.turn2yaw(self,yaw) then - dir.y = y - self.object:set_velocity(dir) end - else - return true + elseif mobkit.turn2yaw(self,yaw) then + dir.y = y + self.object:set_velocity(dir) end end mobkit.queue_high(self,func,prty) @@ -1180,16 +1180,14 @@ function water_life.hq_snake_move(self,prty,anim) mobkit.animate(self,anim) init=false yaw = rad(random(360)) - pos = mobkit.pos_translate2d(pos,yaw,self.view_range+5) + pos = mobkit.pos_translate2d(pos,yaw,self.view_range + 2) getpos = water_life.find_node_under_air(pos,self.view_range) end if getpos then water_life.hq_idle(self,prty+2,5,anim) - water_life.hq_findpath(self,prty+1,getpos, 1.5,0.1,true) - return true - else - return true + water_life.hq_findpath(self,prty+1,getpos, self.view_range * 1.5, 0.1,true) end + return true end mobkit.queue_high(self,func,prty) end diff --git "a/doc/Hippo\342\201\204Seal - LICENSE" "b/doc/Hippo\342\201\204Seal - LICENSE" new file mode 100644 index 0000000..34c4dde --- /dev/null +++ "b/doc/Hippo\342\201\204Seal - LICENSE" @@ -0,0 +1,36 @@ +MIT License + +Copyright (c) 2021 Skandarella + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + +Lincense for original Code (mobs redo + mobs_animal): (MIT) Copyright (c) 2014 Krupnov Pavel and 2016 TenPlus1 + +Modified Code by Liil/Wilhelmine/Liil (c) 2022 +Textures, Models and Animation by Liil/Wilhelmine/Liil under (MIT) License (c) 2022 + +Beluga and Leopard Seal sound by Liil/Wilhelmine/Liil. +Other sounds are from freesound.org under Creative Commons License. Thanks to Lauramel, Gleith, Theveomammoth11, Vataa, D-Jones, Pol, Robinhood76, +sesmo42, Missburusdeer2011, Hazure, Inspectorj, Benboncan, Spookymodem, Drobiumdesign, J-zazvurek, Benboncan, Felix-blume, Sihil, Kabit, Roubignolle, +Egomassive, Florianreichelt, Fxasc, Extrafon, Cognito-perceptu, Jjbubo, Blessedcup, Jaegrover, Yks, Pillonoise, Traade, Tilano408, j0ck0, Mings, Befig, +Stackpool, vilatzara, viorelvio, newagesoup, slunali, fr0608bg, reinsamba, kangaroovindaloo, breviceps, guyburns, tyler7687, navadaux, fairhavencollection, acclivity and sarena6487528 for the sounds! +Thanks to Nagaty Studio for the Hyena Sounds! Source: https://www.youtube.com/c/NagatyStudio/about +Also thanks to Ian Fairley (https://www.youtube.com/channel/UChVk1Pvn-JMWkepnQLK-gCg) for the Zebra sounds. +Thanks to Lars Edenius for the Black Grouse sounds. \ No newline at end of file diff --git a/init.lua b/init.lua index bf09c2e..0c84d7a 100644 --- a/init.lua +++ b/init.lua @@ -6,7 +6,7 @@ ----------------------------------------------------------- water_life = {} -water_life.version = "240316" +water_life.version = "240401" water_life.shark_food = {} water_life.repellant = {} water_life.gull_bait = {} @@ -43,7 +43,7 @@ water_life.moskito_humidity = tonumber(minetest.settings:get("water_life_moskito water_life.moskito_mintemp = tonumber(minetest.settings:get("water_life_moskito_mintemp")) or 20 water_life.radar_debug = minetest.settings:get_bool("water_life_radar_debug") or false -water_life.muddy_water = minetest.settings:get_bool("water_life_muddy_water") or false +water_life.muddy_water = minetest.settings:get_bool("water_life_muddy_water") or true -- the repellent lasts half a minetest day water_life.repeltime = math.floor (720 / (tonumber(minetest.settings:get("time_speed")) or 72)*60) @@ -96,6 +96,7 @@ if not water_life.apionly then dofile(path.."/animals/gulls.lua") dofile(path.."/animals/gecko.lua") dofile(path.."/animals/beaver.lua") + dofile(path.."/animals/hippo.lua") if not water_life.dangerous then dofile(path.."/animals/snake.lua") dofile(path.."/animals/piranha.lua") diff --git a/mod.conf b/mod.conf index 2002bf5..a4f8019 100644 --- a/mod.conf +++ b/mod.conf @@ -2,4 +2,5 @@ name = water_life description = adds new life to your waters depends = mobkit,default optional_depends = bucket,petz,unified_inventory,farming,vessels,flowers,fireflies,mobs +author = Gundul min_minetest_version = 5.5 diff --git a/paths.lua b/paths.lua index 5327e5f..5ccef67 100644 --- a/paths.lua +++ b/paths.lua @@ -4,11 +4,15 @@ local closedSet = {} local random = water_life.random local abs = math.abs -local function show_path(ptable) - if not ptable or #ptable < 1 then return end - + +local function show_path(ptable, duration) + duration = duration or 1 + + if not ptable or #ptable < 1 then + return + end for i= 1,#ptable,1 do - water_life.temp_show(ptable[i],1,1) + water_life.temp_show(ptable[i],duration,1) end end @@ -118,7 +122,7 @@ local function get_neighbor_ground_level(pos, jump_height, fall_height, current_ end end -function water_life.find_path(pos, endpos, entity, dtime, fast) +function water_life.find_path_deprecated(pos, endpos, entity, dtime, fast) if fast then return minetest.find_path(pos,endpos,water_life.abr*16,entity.jump_height,1,"A*") end @@ -322,47 +326,67 @@ function water_life.find_path(pos, endpos, entity, dtime, fast) return {pos} end +function water_life.find_path(pos, endpos, entity, dtime, fast) + local searchdistance = entity.view_range or water_life.abr * 8 + local max_jump = entity.jump_height or 1 + local max_drop = 1 + + return minetest.find_path(pos, endpos, searchdistance, max_jump, max_drop, "A*_noprefetch") +end + +function water_life.show_path(ptable, duration) + show_path(ptable, duration) +end ------------------------------------ -- Bahaviors and helper functions -- ------------------------------------ - function water_life.hq_findpath(self,prty,tpos,dist,speed,fast) mobkit.clear_queue_low(self) - if not dist then dist = 1 end - if not speed then speed = 1 end - local way = water_life.find_path(self.object:get_pos(), tpos, self, self.dtime,fast) - + dist = dist or 0 + speed = speed or 1 + local init = true + local way = {} + local func = function(self) - if not way or #way < 2 then return true end + if init then + local startpos = mobkit.get_stand_pos(self) + way = water_life.find_path(startpos, tpos, self, self.dtime,fast) + if not way then + return true + end + init = false; + end + if #way < 2 then + return true + end if mobkit.is_queue_empty_low(self) and self.isonground then local pos = self.object:get_pos() local pos2 = way[2] - local height = abs(pos.y - pos2.y)-0.5 - local node = mobkit.nodeatpos({x=pos2.x, y=pos2.y -1, z = pos2.z}) - if not node or not node.walkable then return true end - if vector.distance(pos,tpos) > dist then - if height <= 0.01 then - local yaw = self.object:get_yaw() - local tyaw = minetest.dir_to_yaw(vector.direction(self.object:get_pos(),pos2)) - if math.abs(tyaw-yaw) > 1 then - mobkit.lq_turn2pos(self,pos2) - end - mobkit.lq_dumbwalk(self,pos2,speed) - else + pos2 = mobkit.pos_shift(pos2,{y = -0.49}) + local height = pos2.y - pos.y + local node = mobkit.nodeatpos(pos2) + if height <= 0.01 then + local yaw = self.object:get_yaw() + local tyaw = minetest.dir_to_yaw(vector.direction(pos,pos2)) + if math.abs(tyaw-yaw) > 1 then mobkit.lq_turn2pos(self,pos2) - mobkit.lq_dumbjump(self,height) - end - - if vector.distance(pos,pos2) <= 2 then - table.remove(way,2) end + mobkit.lq_dumbwalk(self,pos2,speed) else - return true + mobkit.lq_turn2pos(self,pos2) + mobkit.lq_dumbjump(self,height) + end + + if vector.distance(pos,pos2) <= 1.49 then + table.remove(way, 1) end end + if self.isinliquid then + return true + end end mobkit.queue_high(self,func,prty) end diff --git a/sounds/water_life_hippo_angry1.ogg b/sounds/water_life_hippo_angry1.ogg new file mode 100644 index 0000000..c1d0b91 Binary files /dev/null and b/sounds/water_life_hippo_angry1.ogg differ diff --git a/sounds/water_life_hippo_angry2.ogg b/sounds/water_life_hippo_angry2.ogg new file mode 100644 index 0000000..2e77f42 Binary files /dev/null and b/sounds/water_life_hippo_angry2.ogg differ diff --git a/sounds/water_life_hippo_idle1.ogg b/sounds/water_life_hippo_idle1.ogg new file mode 100644 index 0000000..7877451 Binary files /dev/null and b/sounds/water_life_hippo_idle1.ogg differ diff --git a/sounds/water_life_hippo_idle2.ogg b/sounds/water_life_hippo_idle2.ogg new file mode 100644 index 0000000..a6c72fc Binary files /dev/null and b/sounds/water_life_hippo_idle2.ogg differ diff --git a/sounds/water_life_hippo_idle3.ogg b/sounds/water_life_hippo_idle3.ogg new file mode 100644 index 0000000..e587fbf Binary files /dev/null and b/sounds/water_life_hippo_idle3.ogg differ diff --git a/sounds/water_life_hippo_idle4.ogg b/sounds/water_life_hippo_idle4.ogg new file mode 100644 index 0000000..a8d3cc4 Binary files /dev/null and b/sounds/water_life_hippo_idle4.ogg differ diff --git a/sounds/water_life_hippo_idle5.ogg b/sounds/water_life_hippo_idle5.ogg new file mode 100644 index 0000000..4b71502 Binary files /dev/null and b/sounds/water_life_hippo_idle5.ogg differ diff --git a/spawn.lua b/spawn.lua index cd26d93..e6993cf 100644 --- a/spawn.lua +++ b/spawn.lua @@ -251,6 +251,25 @@ local function spawnstep(dtime) end end + mobname = 'water_life:hippo' + local faktor = 100 - getCount(mobname, animal[mobname]) * 33 + if random(100) < faktor then + local fits = false + if (string.match(bdata.name,"rainforest") or + string.match(bdata.name,"savanna")) and + liquidflag == "muddy" then + fits = true + end + if depth > 3 and fits and pool == false then + local obj = spawn_it_here(animal,surface,mobname) + if obj then + local props = obj:get_properties() + local size = water_life.random(0.5, 1.5) + props.visual_size = {x = size, y = size} + obj:set_properties(props) + end + end + end --[[ mobname = 'water_life:snake' local faktor = (100 - getCount(mobname, animal[mobname]) * 50) +25 diff --git a/textures/water_life_texture_hippo.png b/textures/water_life_hippo.png similarity index 100% rename from textures/water_life_texture_hippo.png rename to textures/water_life_hippo.png diff --git a/textures/water_life_texture_seal.png b/textures/water_life_seal.png similarity index 100% rename from textures/water_life_texture_seal.png rename to textures/water_life_seal.png