catch and tame riverfish
This commit is contained in:
parent
7e7aa0fb7c
commit
3f9e8fd110
21
api.lua
21
api.lua
@ -11,11 +11,18 @@ local sign = math.sign
|
|||||||
|
|
||||||
local time = os.time
|
local time = os.time
|
||||||
|
|
||||||
local abr = minetest.get_mapgen_setting('active_block_range') or 2
|
|
||||||
local abo = minetest.get_mapgen_setting('active_object_send_range_blocks') or 3
|
|
||||||
|
|
||||||
|
|
||||||
function water_life.handle_drops(self) -- drop on death what is definded in the entity table
|
-- throws a coin
|
||||||
|
function water_life.leftorright()
|
||||||
|
local rnd = math.random()
|
||||||
|
if rnd > 0.5 then return true else return false end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- drop on death what is definded in the entity table
|
||||||
|
function water_life.handle_drops(self)
|
||||||
if not self.drops then return end
|
if not self.drops then return end
|
||||||
|
|
||||||
for _,item in ipairs(self.drops) do
|
for _,item in ipairs(self.drops) do
|
||||||
@ -34,6 +41,7 @@ function water_life.handle_drops(self) -- drop on death what is definded in t
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function water_life.register_shark_food(name)
|
function water_life.register_shark_food(name)
|
||||||
table.insert(water_life.shark_food,name)
|
table.insert(water_life.shark_food,name)
|
||||||
end
|
end
|
||||||
@ -44,6 +52,7 @@ function water_life.feed_shark()
|
|||||||
return water_life.shark_food[index]
|
return water_life.shark_food[index]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function water_life.aqua_radar_dumb(pos,yaw,range,reverse)
|
function water_life.aqua_radar_dumb(pos,yaw,range,reverse)
|
||||||
range = range or 4
|
range = range or 4
|
||||||
|
|
||||||
@ -98,7 +107,7 @@ end
|
|||||||
-- counts animals in specified radius or active_object_send_range_blocks, returns a table containing numbers
|
-- counts animals in specified radius or active_object_send_range_blocks, returns a table containing numbers
|
||||||
function water_life.count_objects(pos,radius)
|
function water_life.count_objects(pos,radius)
|
||||||
|
|
||||||
if not radius then radius = abo * 16 end
|
if not radius then radius = water_life.abo * 16 end
|
||||||
|
|
||||||
local all_objects = minetest.get_objects_inside_radius(pos, radius)
|
local all_objects = minetest.get_objects_inside_radius(pos, radius)
|
||||||
local hasil = {}
|
local hasil = {}
|
||||||
@ -114,7 +123,7 @@ for _,obj in ipairs(all_objects) do
|
|||||||
hasil.whales = hasil.whales +1
|
hasil.whales = hasil.whales +1
|
||||||
elseif entity and entity.name == "water_life:shark" then
|
elseif entity and entity.name == "water_life:shark" then
|
||||||
hasil.sharks = hasil.sharks +1
|
hasil.sharks = hasil.sharks +1
|
||||||
elseif entity and entity.name == "water_life:fish" then
|
elseif entity and (entity.name == "water_life:fish" or entity.name == "water_life:fish_tamed") then
|
||||||
hasil.fish = hasil.fish +1
|
hasil.fish = hasil.fish +1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -217,7 +226,7 @@ function water_life.big_aqua_roam(self,prty,speed)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
if mobkit.timer(self,10) then
|
if mobkit.timer(self,10) then
|
||||||
if vector.distance(pos,center) > abo*16*0.5 then
|
if vector.distance(pos,center) > water_life.abo*16*0.5 then
|
||||||
tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5}))
|
tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5}))
|
||||||
else
|
else
|
||||||
if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end
|
if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end
|
||||||
|
27
crafts.lua
27
crafts.lua
@ -22,3 +22,30 @@ minetest.register_craft({
|
|||||||
recipe = "water_life:meat_raw",
|
recipe = "water_life:meat_raw",
|
||||||
cooktime = 5
|
cooktime = 5
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("water_life:riverfish", {
|
||||||
|
description = ("Riverfish"),
|
||||||
|
inventory_image = "water_life_riverfish_item.png",
|
||||||
|
wield_scale = {x = 0.5, y = 0.5, z = 0.5},
|
||||||
|
stack_max = 10,
|
||||||
|
liquids_pointable = false,
|
||||||
|
range = 10,
|
||||||
|
on_use = minetest.item_eat(3),
|
||||||
|
groups = {food_meat = 1, flammable = 2},
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
if placer and not placer:is_player() then return itemstack end
|
||||||
|
if not pointed_thing then return itemstack end
|
||||||
|
if not pointed_thing.type == "node" then return itemstack end
|
||||||
|
|
||||||
|
local pos = pointed_thing.above
|
||||||
|
local number = water_life.count_objects(pos)
|
||||||
|
if number.all > water_life.maxmobs or number.fish > 10 then return itemstack end
|
||||||
|
|
||||||
|
local name = placer:get_player_name()
|
||||||
|
local obj = minetest.add_entity(pos, "water_life:fish_tamed")
|
||||||
|
obj = obj:get_luaentity()
|
||||||
|
itemstack:take_item()
|
||||||
|
obj.owner = name
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
default
|
default
|
||||||
mobkit
|
mobkit
|
||||||
|
fireflies?
|
||||||
|
546
init.lua
546
init.lua
@ -1,6 +1,13 @@
|
|||||||
water_life = {}
|
water_life = {}
|
||||||
water_life.shark_food = {}
|
water_life.shark_food = {}
|
||||||
|
water_life.abr = minetest.get_mapgen_setting('active_block_range') or 2
|
||||||
|
water_life.abo = minetest.get_mapgen_setting('active_object_send_range_blocks') or 3
|
||||||
|
water_life.whale_spawn_rate = 30 -- chances in promille 30 promille = 3%
|
||||||
|
water_life.shark_spawn_rate = 100
|
||||||
|
water_life.fish_spawn_rate = 1000
|
||||||
|
water_life.maxwhales = 1
|
||||||
|
water_life.maxsharks = water_life.abo/2
|
||||||
|
water_life.maxmobs = 30
|
||||||
|
|
||||||
math.randomseed(os.time()) --init random seed
|
math.randomseed(os.time()) --init random seed
|
||||||
|
|
||||||
@ -9,11 +16,11 @@ local path = minetest.get_modpath(minetest.get_current_modname())
|
|||||||
|
|
||||||
dofile(path.."/api.lua") -- load water_life api
|
dofile(path.."/api.lua") -- load water_life api
|
||||||
dofile(path.."/crafts.lua") -- load crafts
|
dofile(path.."/crafts.lua") -- load crafts
|
||||||
|
dofile(path.."/spawn.lua") -- load spawn function
|
||||||
|
dofile(path.."/whale.lua") -- load whales
|
||||||
|
dofile(path.."/shark.lua") -- load sharks
|
||||||
|
dofile(path.."/riverfish.lua") -- load riverfish
|
||||||
|
|
||||||
if minetest.get_modpath("wildlife") then
|
|
||||||
water_life.register_shark_food("wildlife:deer")
|
|
||||||
water_life.register_shark_food("wildlife:wolf")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--remove old sharks
|
--remove old sharks
|
||||||
@ -29,531 +36,12 @@ minetest.register_entity(":zombiestrd:shark", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
local abr = minetest.get_mapgen_setting('active_block_range') or 2
|
|
||||||
local abo = minetest.get_mapgen_setting('active_object_send_range_blocks') or 3
|
|
||||||
local nodename_water = minetest.registered_aliases.mapgen_water_source
|
|
||||||
|
|
||||||
local timer = 0
|
|
||||||
|
|
||||||
local abs = math.abs
|
|
||||||
local pi = math.pi
|
|
||||||
local floor = math.floor
|
|
||||||
local random = math.random
|
|
||||||
local sqrt = math.sqrt
|
|
||||||
local max = math.max
|
|
||||||
local min = math.min
|
|
||||||
local pow = math.pow
|
|
||||||
local sign = math.sign
|
|
||||||
|
|
||||||
local time = os.time
|
|
||||||
|
|
||||||
local whale_spawn_rate = 30
|
|
||||||
local shark_spawn_rate = 100
|
|
||||||
local fish_spawn_rate = 1000
|
|
||||||
local maxwhales = 1
|
|
||||||
local maxsharks = abo/2
|
|
||||||
local maxfish = 10
|
|
||||||
local maxmobs = 30
|
|
||||||
|
|
||||||
-- water_life.register_shark_food("water_life:fish") --fish is too small for sharks
|
|
||||||
-------------------
|
|
||||||
-- Helper Functions
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
|
|
||||||
-- throws a coin
|
-- register shark food
|
||||||
local function leftorright()
|
water_life.register_shark_food("water_life:fish") --fish is too small for sharks
|
||||||
local rnd = math.random()
|
if minetest.get_modpath("wildlife") then
|
||||||
if rnd > 0.5 then return true else return false end
|
water_life.register_shark_food("wildlife:deer")
|
||||||
|
water_life.register_shark_food("wildlife:wolf")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- this is whale specific, so keeping it local
|
|
||||||
local function chose_turn(self,pos,yaw)
|
|
||||||
|
|
||||||
local remember = mobkit.recall(self,"turn")
|
|
||||||
if not remember then
|
|
||||||
if leftorright() then
|
|
||||||
remember = "1"
|
|
||||||
mobkit.remember(self,"time", self.time_total)
|
|
||||||
mobkit.remember(self,"turn", "1")
|
|
||||||
else
|
|
||||||
remember = "0"
|
|
||||||
mobkit.remember(self,"time", self.time_total)
|
|
||||||
mobkit.remember(self,"turn", "0")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local clockpos = mobkit.pos_translate2d(pos,yaw+(pi/4),10)
|
|
||||||
local clockpos1 = mobkit.pos_shift(clockpos,{x=-3,y=-2,z=-3})
|
|
||||||
clockpos = mobkit.pos_shift(clockpos,{x=3,y=3,z=3})
|
|
||||||
local revpos = mobkit.pos_translate2d(pos,yaw-(pi/4),10)
|
|
||||||
local revpos1 = mobkit.pos_shift(revpos,{x=-3,y=-2,z=-3})
|
|
||||||
revpos = mobkit.pos_shift(revpos,{x=3,y=3,z=3})
|
|
||||||
|
|
||||||
local ccheck= minetest.find_nodes_in_area(clockpos,clockpos1, {"group:water","default:sand_with_kelp"})
|
|
||||||
local rcheck = minetest.find_nodes_in_area(revpos,revpos1, {"group:water","default:sand_with_kelp"})
|
|
||||||
--minetest.chat_send_all(dump(#rcheck).." : "..dump(#ccheck).." "..dump(remember).." --> "..dump(self.isonground))
|
|
||||||
local a = #ccheck
|
|
||||||
local b = #rcheck
|
|
||||||
|
|
||||||
if a > b+15 then
|
|
||||||
mobkit.remember(self,"turn", "1")
|
|
||||||
mobkit.remember(self,"time", self.time_total)
|
|
||||||
return false
|
|
||||||
|
|
||||||
elseif a < b-15 then
|
|
||||||
mobkit.remember(self,"turn","0")
|
|
||||||
mobkit.remember(self,"time", self.time_total)
|
|
||||||
return true
|
|
||||||
|
|
||||||
else
|
|
||||||
|
|
||||||
if remember == "0" then return true else return false end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-----------------
|
|
||||||
-- Spawn Function
|
|
||||||
-----------------
|
|
||||||
|
|
||||||
|
|
||||||
local function spawnstep(dtime)
|
|
||||||
|
|
||||||
timer = timer + dtime
|
|
||||||
if timer > 5 then
|
|
||||||
|
|
||||||
for _,plyr in ipairs(minetest.get_connected_players()) do
|
|
||||||
|
|
||||||
local coin = random(1000)
|
|
||||||
--minetest.chat_send_all(dump(coin))
|
|
||||||
if plyr then -- each player gets a spawn chance every 5s on average
|
|
||||||
|
|
||||||
local pos = plyr:get_pos()
|
|
||||||
local yaw = plyr:get_look_horizontal()
|
|
||||||
local chance = shark_spawn_rate
|
|
||||||
|
|
||||||
local animal = water_life.count_objects(pos)
|
|
||||||
|
|
||||||
--minetest.chat_send_all("yaw = "..dump(yaw).." mobs: "..dump(all_objects).." sharks: "..dump(ms).." whales: "..dump(mw))
|
|
||||||
if animal.all > maxmobs then break end
|
|
||||||
|
|
||||||
-- find a pos randomly in look direction of player
|
|
||||||
local radius = (abo * 12) - 1 -- 75% from 16 = 12 nodes
|
|
||||||
radius = math.random(7,radius)
|
|
||||||
local angel = math.random() * (pi/4) -- look for random angel 0 - 45 degrees
|
|
||||||
if leftorright() then yaw = yaw + angel else yaw = yaw - angel end -- add or substract to/from yaw
|
|
||||||
|
|
||||||
local pos2 = mobkit.pos_translate2d(pos,yaw,radius)
|
|
||||||
|
|
||||||
|
|
||||||
local height, liquidflag = mobkit.get_terrain_height(pos2,32)
|
|
||||||
--minetest.chat_send_all(dump(height).." "..dump(liquidflag))
|
|
||||||
|
|
||||||
if height and liquidflag then
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local mobname = 'water_life:shark'
|
|
||||||
if shark_spawn_rate >= coin then
|
|
||||||
pos2.y = height+1.01
|
|
||||||
|
|
||||||
local a=pos2.x
|
|
||||||
local b=pos2.y
|
|
||||||
local c=pos2.z
|
|
||||||
|
|
||||||
local water = minetest.find_nodes_in_area({x=a-3, y=b-3, z=c-3}, {x=a+4, y=b+4, z=c+4}, {"default:water_source"})
|
|
||||||
|
|
||||||
if #water < 128 then break end -- sharks need water, much water
|
|
||||||
|
|
||||||
if animal.sharks > (maxsharks-1) then break end -- sharks are no sardines
|
|
||||||
|
|
||||||
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
local mobname = 'water_life:fish'
|
|
||||||
if fish_spawn_rate >= coin then
|
|
||||||
pos2.y = height+1.01
|
|
||||||
|
|
||||||
local a=pos2.x
|
|
||||||
local b=pos2.y
|
|
||||||
local c=pos2.z
|
|
||||||
|
|
||||||
local nearlife = water_life.count_objects(pos2,16)
|
|
||||||
local water = minetest.find_nodes_in_area({x=a-2, y=b-2, z=c-2}, {x=a+2, y=b+2, z=c+2}, {"default:river_water_source"})
|
|
||||||
|
|
||||||
if water and #water < 10 then break end -- little fish need little water
|
|
||||||
--minetest.chat_send_all("water ="..dump(#water).." mobs="..dump(all_objects))
|
|
||||||
|
|
||||||
if animal.all > (maxmobs-5) or nearlife.fish > 5 then break end
|
|
||||||
|
|
||||||
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
|
||||||
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if whale_spawn_rate >= coin then
|
|
||||||
pos2.y = height+4.01
|
|
||||||
|
|
||||||
mobname = 'water_life:whale'
|
|
||||||
local a=pos2.x
|
|
||||||
local b=pos2.y
|
|
||||||
local c=pos2.z
|
|
||||||
|
|
||||||
local water = minetest.find_nodes_in_area({x=a-5, y=b-5, z=c-5}, {x=a+5, y=b+5, z=c+5}, {"default:water_source"})
|
|
||||||
|
|
||||||
if #water < 900 then break end -- whales need water, much water
|
|
||||||
|
|
||||||
if animal.whales > (maxwhales-1) then break end -- whales are no sardines
|
|
||||||
|
|
||||||
|
|
||||||
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
timer = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_globalstep(spawnstep)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-------------
|
|
||||||
-- The Brains
|
|
||||||
-------------
|
|
||||||
|
|
||||||
local function whale_brain(self)
|
|
||||||
|
|
||||||
if self.hp <= 0 then
|
|
||||||
mobkit.clear_queue_high(self)
|
|
||||||
water_life.handle_drops(self)
|
|
||||||
mobkit.make_sound(self,"death")
|
|
||||||
mobkit.hq_die(self)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- check every 2 seconds what is under whale's belly
|
|
||||||
if mobkit.timer(self,2) then
|
|
||||||
local stand = mobkit.get_stand_pos(self)
|
|
||||||
if stand then stand.y = stand.y - 1 end
|
|
||||||
|
|
||||||
local node = mobkit.nodeatpos(stand)
|
|
||||||
if node then
|
|
||||||
if node.name ~= "default:water_source" then
|
|
||||||
mobkit.hurt(self, 20)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- big animals need to avoid obstacles
|
|
||||||
|
|
||||||
|
|
||||||
if mobkit.timer(self,1) then
|
|
||||||
local remember = mobkit.recall(self,"time")
|
|
||||||
if remember then
|
|
||||||
if self.time_total - remember > 59 then
|
|
||||||
mobkit.forget(self,"turn")
|
|
||||||
mobkit.forget(self,"time")
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local yaw = self.object:get_yaw() + pi
|
|
||||||
local pos = mobkit.get_stand_pos(self)
|
|
||||||
|
|
||||||
local spos = mobkit.pos_translate2d(pos,yaw,15)
|
|
||||||
local hpos = mobkit.pos_translate2d(pos,yaw,6)
|
|
||||||
local head = mobkit.pos_shift(hpos,{y=4})
|
|
||||||
local node = minetest.get_node(head)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local left = mobkit.pos_shift(spos,{x=-3,y=3,z=-3})
|
|
||||||
local right = mobkit.pos_shift(spos,{x=3,y=3,z=3})
|
|
||||||
|
|
||||||
|
|
||||||
local up = mobkit.pos_shift(spos,{x=-1,y=3,z=-1})
|
|
||||||
local down = mobkit.pos_shift(spos,{x=1,y=-2,z=1})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
yaw = yaw - pi
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if node then -- anything above head ? dive.
|
|
||||||
|
|
||||||
if node.name ~= "default:water_source" and node.name ~= "air" then
|
|
||||||
local hvel = vector.multiply(vector.normalize({x=head.x,y=0,z=head.z}),4)
|
|
||||||
self.object:set_velocity({x=hvel.x,y=-1,z=hvel.z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local vcheck= minetest.find_nodes_in_area(up,down, {"default:water_source"})
|
|
||||||
local hcheck = minetest.find_nodes_in_area(left,right, {"default:water_source"})
|
|
||||||
--minetest.chat_send_all(dump(#vcheck).." - "..dump(#hcheck))
|
|
||||||
if #vcheck < 54 or #hcheck < 49 then
|
|
||||||
--mobkit.clear_queue_high(self)
|
|
||||||
if chose_turn(self,pos,yaw) then
|
|
||||||
water_life.big_hq_aqua_turn(self,30,yaw+(pi/24),-0.5)
|
|
||||||
else
|
|
||||||
water_life.big_hq_aqua_turn(self,30,yaw-(pi/24),-0.5)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
if mobkit.is_queue_empty_high(self) then water_life.big_aqua_roam(self,20,-1) end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
local function shark_brain(self)
|
|
||||||
if self.hp <= 0 then
|
|
||||||
mobkit.clear_queue_high(self)
|
|
||||||
water_life.handle_drops(self)
|
|
||||||
mobkit.hq_die(self)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if mobkit.timer(self,1) then
|
|
||||||
|
|
||||||
local whale = mobkit.get_closest_entity(self,"water_life:whale")
|
|
||||||
if whale then
|
|
||||||
local spos = self.object:get_pos()
|
|
||||||
local wpos = whale:get_pos()
|
|
||||||
local distance = math.floor(vector.distance(spos,wpos))
|
|
||||||
if distance < 15 then
|
|
||||||
local yaw = self.object:get_yaw()
|
|
||||||
mobkit.clear_queue_high(self)
|
|
||||||
mobkit.hq_aqua_turn(self,40,yaw+(pi/2),5)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local prty = mobkit.get_queue_priority(self)
|
|
||||||
if prty < 20 then
|
|
||||||
local target = mobkit.get_nearby_player(self)
|
|
||||||
local foodname = water_life.feed_shark()
|
|
||||||
local food = mobkit.get_nearby_entity(self,foodname)
|
|
||||||
if target and mobkit.is_alive(target) and mobkit.is_in_deep(target) and target:get_attach() == nil then
|
|
||||||
mobkit.hq_aqua_attack(self,20,target,9)
|
|
||||||
end
|
|
||||||
|
|
||||||
if food and mobkit.is_in_deep(food) then
|
|
||||||
mobkit.clear_queue_high(self)
|
|
||||||
mobkit.hq_aqua_attack(self,30,food,7)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if mobkit.is_queue_empty_high(self) then mobkit.hq_aqua_roam(self,10,5) end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function fish_brain(self)
|
|
||||||
if self.hp <= 0 then
|
|
||||||
mobkit.clear_queue_high(self)
|
|
||||||
water_life.handle_drops(self)
|
|
||||||
mobkit.hq_die(self)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if mobkit.timer(self,1) then
|
|
||||||
local plyr = mobkit.get_nearby_player(self)
|
|
||||||
if plyr then
|
|
||||||
water_life.hq_swimfrom(self,50,plyr,3)
|
|
||||||
end
|
|
||||||
if mobkit.is_queue_empty_high(self) then mobkit.hq_aqua_roam(self,10,1) end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
---------------
|
|
||||||
-- the Entities
|
|
||||||
---------------
|
|
||||||
|
|
||||||
minetest.register_entity("water_life:whale",{
|
|
||||||
-- common props
|
|
||||||
physical = true,
|
|
||||||
stepheight = 0.1, --EVIL!
|
|
||||||
weight = 250,
|
|
||||||
collide_with_objects = false,
|
|
||||||
collisionbox = {-3, -2, -3, 3, 2, 3},
|
|
||||||
visual = "mesh",
|
|
||||||
mesh = "water_life_whale.b3d",
|
|
||||||
textures = {"water_life_whale.png"},
|
|
||||||
visual_size = {x = 3.5, y = 3.5},
|
|
||||||
drops = {
|
|
||||||
{name = "default:diamond", chance = 5, min = 10, max = 50,},
|
|
||||||
{name = "water_life:meat_raw", chance = 1, min = 15, max = 65,},
|
|
||||||
},
|
|
||||||
static_save = false,
|
|
||||||
makes_footstep_sound = true,
|
|
||||||
on_step = mobkit.stepfunc, -- required
|
|
||||||
on_activate = mobkit.actfunc, -- required
|
|
||||||
get_staticdata = mobkit.statfunc,
|
|
||||||
-- api props
|
|
||||||
springiness=0,
|
|
||||||
buoyancy = 0.98, -- portion of hitbox submerged
|
|
||||||
max_speed = -1,
|
|
||||||
jump_height = 1.26,
|
|
||||||
view_range = 32,
|
|
||||||
-- lung_capacity = 0, -- seconds
|
|
||||||
max_hp = 500,
|
|
||||||
timeout=300,
|
|
||||||
attack={range=4.5,damage_groups={fleshy=15}},
|
|
||||||
sounds = {
|
|
||||||
random = "water_life_whale.ogg",
|
|
||||||
death = "water_life_whale.ogg",
|
|
||||||
distance = 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
animation = {
|
|
||||||
def={range={x=1,y=59},speed=5,loop=true},
|
|
||||||
fast={range={x=1,y=59},speed=20,loop=true},
|
|
||||||
back={range={x=15,y=1},speed=7,loop=false},
|
|
||||||
},
|
|
||||||
|
|
||||||
brainfunc = whale_brain,
|
|
||||||
|
|
||||||
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
|
||||||
if mobkit.is_alive(self) then
|
|
||||||
local obj = self.object
|
|
||||||
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})
|
|
||||||
self.object:add_velocity({x=0,y=-5, z=0})
|
|
||||||
|
|
||||||
|
|
||||||
if time_from_last_punch > 2 then
|
|
||||||
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
|
||||||
else
|
|
||||||
if puncher:is_player() then
|
|
||||||
minetest.chat_send_player(puncher:get_player_name(),">>> You missed <<<")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
obj:set_nametag_attributes({
|
|
||||||
color = '#ff7373',
|
|
||||||
text = ">>> "..tostring(math.floor(self.hp/5)).."% <<<",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_entity("water_life:shark",{
|
|
||||||
-- common props
|
|
||||||
physical = true,
|
|
||||||
stepheight = 0.1, --EVIL!
|
|
||||||
collide_with_objects = false,
|
|
||||||
collisionbox = {-0.5, -0.3, -0.5, 0.5, 0.3, 0.5},
|
|
||||||
visual = "mesh",
|
|
||||||
mesh = "water_life_shark.b3d",
|
|
||||||
textures = {"water_life_shark3tex.png"},
|
|
||||||
visual_size = {x = 1.5, y = 1.5},
|
|
||||||
static_save = false,
|
|
||||||
makes_footstep_sound = true,
|
|
||||||
on_step = mobkit.stepfunc, -- required
|
|
||||||
on_activate = mobkit.actfunc, -- required
|
|
||||||
get_staticdata = mobkit.statfunc,
|
|
||||||
-- api props
|
|
||||||
springiness=0,
|
|
||||||
buoyancy = 0.98, -- portion of hitbox submerged
|
|
||||||
max_speed = 9,
|
|
||||||
jump_height = 1.26,
|
|
||||||
view_range = abo * 12,
|
|
||||||
-- lung_capacity = 0, -- seconds
|
|
||||||
max_hp = 50,
|
|
||||||
timeout=60,
|
|
||||||
drops = {
|
|
||||||
{name = "default:diamond", chance = 5, min = 1, max = 5,},
|
|
||||||
{name = "water_life:meat_raw", chance = 2, min = 1, max = 5,},
|
|
||||||
},
|
|
||||||
attack={range=0.8,damage_groups={fleshy=7}},
|
|
||||||
--sounds = {
|
|
||||||
-- attack='water_life_sharkattack',
|
|
||||||
-- },
|
|
||||||
animation = {
|
|
||||||
def={range={x=1,y=59},speed=40,loop=true},
|
|
||||||
fast={range={x=1,y=59},speed=80,loop=true},
|
|
||||||
back={range={x=15,y=1},speed=-15,loop=false},
|
|
||||||
},
|
|
||||||
|
|
||||||
brainfunc = shark_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})
|
|
||||||
|
|
||||||
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
|
||||||
|
|
||||||
if type(puncher)=='userdata' and puncher:is_player() then -- if hit by a player
|
|
||||||
mobkit.clear_queue_high(self) -- abandon whatever they've been doing
|
|
||||||
mobkit.hq_aqua_attack(self,20,puncher,6) -- get revenge
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_entity("water_life:fish",{
|
|
||||||
-- common props
|
|
||||||
physical = true,
|
|
||||||
stepheight = 0.1, --EVIL!
|
|
||||||
collide_with_objects = false,
|
|
||||||
collisionbox = {-0.1, -0.1, -0.1, 0.1, 0.1, 0.1},
|
|
||||||
visual = "mesh",
|
|
||||||
mesh = "water_life_riverfish.b3d",
|
|
||||||
textures = {"water_life_riverfish.png"},
|
|
||||||
visual_size = {x = 2.5, y = 2.5},
|
|
||||||
static_save = false,
|
|
||||||
makes_footstep_sound = true,
|
|
||||||
on_step = mobkit.stepfunc, -- required
|
|
||||||
on_activate = mobkit.actfunc, -- required
|
|
||||||
get_staticdata = mobkit.statfunc,
|
|
||||||
-- api props
|
|
||||||
springiness=0,
|
|
||||||
buoyancy = 1.07, -- portion of hitbox submerged
|
|
||||||
max_speed = 3, -- negative speed as long as model is not rotatet in head direction
|
|
||||||
jump_height = 0.5,
|
|
||||||
view_range = 4,
|
|
||||||
-- lung_capacity = 0, -- seconds
|
|
||||||
max_hp = 10,
|
|
||||||
timeout=60,
|
|
||||||
drops = {
|
|
||||||
{name = "default:diamond", chance = 20, min = 1, max = 1,},
|
|
||||||
{name = "water_life:meat_raw", chance = 2, min = 1, max = 1,},
|
|
||||||
},
|
|
||||||
animation = {
|
|
||||||
def={range={x=1,y=35},speed=40,loop=true},
|
|
||||||
fast={range={x=1,y=35},speed=80,loop=true},
|
|
||||||
idle={range={x=36,y=75},speed=20,loop=true},
|
|
||||||
},
|
|
||||||
brainfunc = fish_brain,
|
|
||||||
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
|
||||||
if mobkit.is_alive(self) then
|
|
||||||
|
|
||||||
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
|
||||||
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
145
riverfish.lua
Normal file
145
riverfish.lua
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function fish_brain(self)
|
||||||
|
if self.hp <= 0 then
|
||||||
|
mobkit.clear_queue_high(self)
|
||||||
|
water_life.handle_drops(self)
|
||||||
|
mobkit.hq_die(self)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if mobkit.timer(self,1) then
|
||||||
|
local plyr = mobkit.get_nearby_player(self)
|
||||||
|
if plyr and self.wild then
|
||||||
|
water_life.hq_swimfrom(self,50,plyr,3)
|
||||||
|
end
|
||||||
|
if mobkit.is_queue_empty_high(self) then mobkit.hq_aqua_roam(self,10,1) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
-- the Entities
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_entity("water_life:fish",{
|
||||||
|
-- common props
|
||||||
|
physical = true,
|
||||||
|
stepheight = 0.3,
|
||||||
|
collide_with_objects = false,
|
||||||
|
collisionbox = {-0.15, -0.15, -0.15, 0.15, 0.15, 0.15},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "water_life_riverfish.b3d",
|
||||||
|
textures = {"water_life_riverfish.png"},
|
||||||
|
visual_size = {x = 2.5, y = 2.5},
|
||||||
|
static_save = false,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
on_step = mobkit.stepfunc, -- required
|
||||||
|
on_activate = mobkit.actfunc, -- required
|
||||||
|
get_staticdata = mobkit.statfunc,
|
||||||
|
-- api props
|
||||||
|
springiness=0,
|
||||||
|
buoyancy = 1.07, -- portion of hitbox submerged
|
||||||
|
max_speed = 3,
|
||||||
|
jump_height = 0.5,
|
||||||
|
view_range = 4,
|
||||||
|
-- lung_capacity = 0, -- seconds
|
||||||
|
max_hp = 10,
|
||||||
|
timeout=60,
|
||||||
|
wild = true,
|
||||||
|
drops = {
|
||||||
|
{name = "default:diamond", chance = 20, min = 1, max = 1,},
|
||||||
|
{name = "water_life:meat_raw", chance = 2, min = 1, max = 1,},
|
||||||
|
},
|
||||||
|
animation = {
|
||||||
|
def={range={x=1,y=35},speed=40,loop=true},
|
||||||
|
fast={range={x=1,y=35},speed=80,loop=true},
|
||||||
|
idle={range={x=36,y=75},speed=20,loop=true},
|
||||||
|
},
|
||||||
|
brainfunc = fish_brain,
|
||||||
|
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||||
|
if mobkit.is_alive(self) then
|
||||||
|
|
||||||
|
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_rightclick = function(self, clicker)
|
||||||
|
if not clicker or not clicker:is_player() then return end
|
||||||
|
local inv = clicker:get_inventory()
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
|
||||||
|
if not item or item:get_name() ~= "fireflies:bug_net" then return end
|
||||||
|
if not inv:room_for_item("main", "water_life:fish") then return end
|
||||||
|
|
||||||
|
inv:add_item("main", "water_life:riverfish")
|
||||||
|
self.object:remove()
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_entity("water_life:fish_tamed",{
|
||||||
|
-- common props
|
||||||
|
physical = true,
|
||||||
|
stepheight = 0.3,
|
||||||
|
collide_with_objects = false,
|
||||||
|
collisionbox = {-0.15, -0.15, -0.15, 0.15, 0.15, 0.15},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "water_life_riverfish.b3d",
|
||||||
|
textures = {"water_life_riverfish_tamed.png"},
|
||||||
|
visual_size = {x = 2.5, y = 2.5},
|
||||||
|
static_save = true,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
on_step = mobkit.stepfunc, -- required
|
||||||
|
on_activate = mobkit.actfunc, -- required
|
||||||
|
get_staticdata = mobkit.statfunc,
|
||||||
|
-- api props
|
||||||
|
springiness=0,
|
||||||
|
buoyancy = 1.07, -- portion of hitbox submerged
|
||||||
|
max_speed = 3,
|
||||||
|
jump_height = 0.5,
|
||||||
|
view_range = 4,
|
||||||
|
-- lung_capacity = 0, -- seconds
|
||||||
|
max_hp = 10,
|
||||||
|
timeout=60,
|
||||||
|
wild = false,
|
||||||
|
owner = "",
|
||||||
|
drops = {
|
||||||
|
{name = "default:diamond", chance = 20, min = 1, max = 1,},
|
||||||
|
{name = "water_life:meat_raw", chance = 2, min = 1, max = 1,},
|
||||||
|
},
|
||||||
|
animation = {
|
||||||
|
def={range={x=1,y=35},speed=40,loop=true},
|
||||||
|
fast={range={x=1,y=35},speed=80,loop=true},
|
||||||
|
idle={range={x=36,y=75},speed=20,loop=true},
|
||||||
|
},
|
||||||
|
brainfunc = fish_brain,
|
||||||
|
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||||
|
if mobkit.is_alive(self) then
|
||||||
|
|
||||||
|
|
||||||
|
if self.owner and self.owner ~= puncher:get_player_name() and self.owner ~= "" then return end
|
||||||
|
if not puncher or not puncher:is_player() then return end
|
||||||
|
|
||||||
|
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
||||||
|
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_rightclick = function(self, clicker)
|
||||||
|
if not clicker or not clicker:is_player() then return end
|
||||||
|
local inv = clicker:get_inventory()
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
|
||||||
|
if not item or item:get_name() ~= "fireflies:bug_net" then return end
|
||||||
|
if not inv:room_for_item("main", "water_life:fish") then return end
|
||||||
|
if self.owner and self.owner ~= clicker:get_player_name() and self.owner ~= "" then return end
|
||||||
|
|
||||||
|
inv:add_item("main", "water_life:riverfish")
|
||||||
|
self.object:remove()
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
109
shark.lua
Normal file
109
shark.lua
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
|
||||||
|
local abs = math.abs
|
||||||
|
local pi = math.pi
|
||||||
|
local floor = math.floor
|
||||||
|
local random = math.random
|
||||||
|
local sqrt = math.sqrt
|
||||||
|
local max = math.max
|
||||||
|
local min = math.min
|
||||||
|
local pow = math.pow
|
||||||
|
local sign = math.sign
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local function shark_brain(self)
|
||||||
|
if self.hp <= 0 then
|
||||||
|
mobkit.clear_queue_high(self)
|
||||||
|
water_life.handle_drops(self)
|
||||||
|
mobkit.hq_die(self)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if mobkit.timer(self,1) then
|
||||||
|
|
||||||
|
local whale = mobkit.get_closest_entity(self,"water_life:whale")
|
||||||
|
if whale then
|
||||||
|
local spos = self.object:get_pos()
|
||||||
|
local wpos = whale:get_pos()
|
||||||
|
local distance = math.floor(vector.distance(spos,wpos))
|
||||||
|
if distance < 15 then
|
||||||
|
local yaw = self.object:get_yaw()
|
||||||
|
mobkit.clear_queue_high(self)
|
||||||
|
mobkit.hq_aqua_turn(self,40,yaw+(pi/2),5)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local prty = mobkit.get_queue_priority(self)
|
||||||
|
if prty < 20 then
|
||||||
|
local target = mobkit.get_nearby_player(self)
|
||||||
|
local foodname = water_life.feed_shark()
|
||||||
|
local food = mobkit.get_nearby_entity(self,foodname)
|
||||||
|
if target and mobkit.is_alive(target) and mobkit.is_in_deep(target) and target:get_attach() == nil then
|
||||||
|
mobkit.hq_aqua_attack(self,20,target,9)
|
||||||
|
end
|
||||||
|
|
||||||
|
if food and mobkit.is_in_deep(food) then
|
||||||
|
mobkit.clear_queue_high(self)
|
||||||
|
mobkit.hq_aqua_attack(self,30,food,7)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if mobkit.is_queue_empty_high(self) then mobkit.hq_aqua_roam(self,10,5) end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_entity("water_life:shark",{
|
||||||
|
-- common props
|
||||||
|
physical = true,
|
||||||
|
stepheight = 0.1, --EVIL!
|
||||||
|
collide_with_objects = false,
|
||||||
|
collisionbox = {-0.5, -0.3, -0.5, 0.5, 0.3, 0.5},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "water_life_shark.b3d",
|
||||||
|
textures = {"water_life_shark3tex.png"},
|
||||||
|
visual_size = {x = 1.5, y = 1.5},
|
||||||
|
static_save = false,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
on_step = mobkit.stepfunc, -- required
|
||||||
|
on_activate = mobkit.actfunc, -- required
|
||||||
|
get_staticdata = mobkit.statfunc,
|
||||||
|
-- api props
|
||||||
|
springiness=0,
|
||||||
|
buoyancy = 0.98, -- portion of hitbox submerged
|
||||||
|
max_speed = 9,
|
||||||
|
jump_height = 1.26,
|
||||||
|
view_range = water_life.abo * 12,
|
||||||
|
-- lung_capacity = 0, -- seconds
|
||||||
|
max_hp = 50,
|
||||||
|
timeout=60,
|
||||||
|
drops = {
|
||||||
|
{name = "default:diamond", chance = 5, min = 1, max = 5,},
|
||||||
|
{name = "water_life:meat_raw", chance = 2, min = 1, max = 5,},
|
||||||
|
},
|
||||||
|
attack={range=0.8,damage_groups={fleshy=7}},
|
||||||
|
--sounds = {
|
||||||
|
-- attack='water_life_sharkattack',
|
||||||
|
-- },
|
||||||
|
animation = {
|
||||||
|
def={range={x=1,y=59},speed=40,loop=true},
|
||||||
|
fast={range={x=1,y=59},speed=80,loop=true},
|
||||||
|
back={range={x=15,y=1},speed=-15,loop=false},
|
||||||
|
},
|
||||||
|
|
||||||
|
brainfunc = shark_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})
|
||||||
|
|
||||||
|
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
||||||
|
|
||||||
|
if type(puncher)=='userdata' and puncher:is_player() then -- if hit by a player
|
||||||
|
mobkit.clear_queue_high(self) -- abandon whatever they've been doing
|
||||||
|
mobkit.hq_aqua_attack(self,20,puncher,6) -- get revenge
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
108
spawn.lua
Normal file
108
spawn.lua
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
local timer = 0
|
||||||
|
local pi = math.pi
|
||||||
|
|
||||||
|
|
||||||
|
local function spawnstep(dtime)
|
||||||
|
|
||||||
|
timer = timer + dtime
|
||||||
|
if timer > 5 then
|
||||||
|
|
||||||
|
for _,plyr in ipairs(minetest.get_connected_players()) do
|
||||||
|
|
||||||
|
local coin = math.random(1000)
|
||||||
|
--minetest.chat_send_all(dump(coin))
|
||||||
|
if plyr then -- each player gets a spawn chance every 5s on average
|
||||||
|
|
||||||
|
local pos = plyr:get_pos()
|
||||||
|
local yaw = plyr:get_look_horizontal()
|
||||||
|
|
||||||
|
local animal = water_life.count_objects(pos)
|
||||||
|
|
||||||
|
--minetest.chat_send_all("yaw = "..dump(yaw).." mobs: "..dump(all_objects).." sharks: "..dump(ms).." whales: "..dump(mw))
|
||||||
|
if animal.all > water_life.maxmobs then break end
|
||||||
|
|
||||||
|
-- find a pos randomly in look direction of player
|
||||||
|
local radius = (water_life.abo * 12) - 1 -- 75% from 16 = 12 nodes
|
||||||
|
radius = math.random(7,radius)
|
||||||
|
local angel = math.random() * (pi/4) -- look for random angel 0 - 45 degrees
|
||||||
|
if water_life.leftorright() then yaw = yaw + angel else yaw = yaw - angel end -- add or substract to/from yaw
|
||||||
|
|
||||||
|
local pos2 = mobkit.pos_translate2d(pos,yaw,radius)
|
||||||
|
|
||||||
|
|
||||||
|
local height, liquidflag = mobkit.get_terrain_height(pos2,32)
|
||||||
|
--minetest.chat_send_all(dump(height).." "..dump(liquidflag))
|
||||||
|
|
||||||
|
if height and liquidflag then
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local mobname = 'water_life:shark'
|
||||||
|
if water_life.shark_spawn_rate >= coin then
|
||||||
|
pos2.y = height+1.01
|
||||||
|
|
||||||
|
local a=pos2.x
|
||||||
|
local b=pos2.y
|
||||||
|
local c=pos2.z
|
||||||
|
|
||||||
|
local water = minetest.find_nodes_in_area({x=a-3, y=b-3, z=c-3}, {x=a+4, y=b+4, z=c+4}, {"default:water_source"})
|
||||||
|
|
||||||
|
if #water < 128 then break end -- sharks need water, much water
|
||||||
|
|
||||||
|
if animal.sharks > (water_life.maxsharks-1) then break end -- sharks are no sardines
|
||||||
|
|
||||||
|
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
local mobname = 'water_life:fish'
|
||||||
|
if water_life.fish_spawn_rate >= coin then
|
||||||
|
pos2.y = height+1.01
|
||||||
|
|
||||||
|
local a=pos2.x
|
||||||
|
local b=pos2.y
|
||||||
|
local c=pos2.z
|
||||||
|
|
||||||
|
local nearlife = water_life.count_objects(pos2,16)
|
||||||
|
local water = minetest.find_nodes_in_area({x=a-2, y=b-2, z=c-2}, {x=a+2, y=b+2, z=c+2}, {"default:river_water_source"})
|
||||||
|
|
||||||
|
if water and #water < 10 then break end -- little fish need little water
|
||||||
|
--minetest.chat_send_all("water ="..dump(#water).." mobs="..dump(all_objects))
|
||||||
|
|
||||||
|
if animal.all > (water_life.maxmobs-5) or nearlife.fish > 5 then break end
|
||||||
|
|
||||||
|
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
if water_life.whale_spawn_rate >= coin then
|
||||||
|
pos2.y = height+4.01
|
||||||
|
|
||||||
|
mobname = 'water_life:whale'
|
||||||
|
local a=pos2.x
|
||||||
|
local b=pos2.y
|
||||||
|
local c=pos2.z
|
||||||
|
|
||||||
|
local water = minetest.find_nodes_in_area({x=a-5, y=b-5, z=c-5}, {x=a+5, y=b+5, z=c+5}, {"default:water_source"})
|
||||||
|
|
||||||
|
if #water < 900 then break end -- whales need water, much water
|
||||||
|
|
||||||
|
if animal.whales > (water_life.maxwhales-1) then break end -- whales are no sardines
|
||||||
|
|
||||||
|
|
||||||
|
local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
timer = 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_globalstep(spawnstep)
|
||||||
|
|
BIN
textures/water_life_riverfish_item.png
Normal file
BIN
textures/water_life_riverfish_item.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
textures/water_life_riverfish_tamed.png
Normal file
BIN
textures/water_life_riverfish_tamed.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 798 B |
223
whale.lua
Normal file
223
whale.lua
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
|
||||||
|
local abs = math.abs
|
||||||
|
local pi = math.pi
|
||||||
|
local floor = math.floor
|
||||||
|
local random = math.random
|
||||||
|
local sqrt = math.sqrt
|
||||||
|
local max = math.max
|
||||||
|
local min = math.min
|
||||||
|
local pow = math.pow
|
||||||
|
local sign = math.sign
|
||||||
|
|
||||||
|
-- this is whale specific, so keeping it local
|
||||||
|
local function chose_turn(self,pos,yaw)
|
||||||
|
|
||||||
|
local remember = mobkit.recall(self,"turn")
|
||||||
|
if not remember then
|
||||||
|
if water_life.leftorright() then
|
||||||
|
remember = "1"
|
||||||
|
mobkit.remember(self,"time", self.time_total)
|
||||||
|
mobkit.remember(self,"turn", "1")
|
||||||
|
else
|
||||||
|
remember = "0"
|
||||||
|
mobkit.remember(self,"time", self.time_total)
|
||||||
|
mobkit.remember(self,"turn", "0")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local clockpos = mobkit.pos_translate2d(pos,yaw+(pi/4),10)
|
||||||
|
local clockpos1 = mobkit.pos_shift(clockpos,{x=-3,y=-2,z=-3})
|
||||||
|
clockpos = mobkit.pos_shift(clockpos,{x=3,y=3,z=3})
|
||||||
|
local revpos = mobkit.pos_translate2d(pos,yaw-(pi/4),10)
|
||||||
|
local revpos1 = mobkit.pos_shift(revpos,{x=-3,y=-2,z=-3})
|
||||||
|
revpos = mobkit.pos_shift(revpos,{x=3,y=3,z=3})
|
||||||
|
|
||||||
|
local ccheck= minetest.find_nodes_in_area(clockpos,clockpos1, {"group:water","default:sand_with_kelp"})
|
||||||
|
local rcheck = minetest.find_nodes_in_area(revpos,revpos1, {"group:water","default:sand_with_kelp"})
|
||||||
|
--minetest.chat_send_all(dump(#rcheck).." : "..dump(#ccheck).." "..dump(remember).." --> "..dump(self.isonground))
|
||||||
|
local a = #ccheck
|
||||||
|
local b = #rcheck
|
||||||
|
|
||||||
|
if a > b+15 then
|
||||||
|
mobkit.remember(self,"turn", "1")
|
||||||
|
mobkit.remember(self,"time", self.time_total)
|
||||||
|
return false
|
||||||
|
|
||||||
|
elseif a < b-15 then
|
||||||
|
mobkit.remember(self,"turn","0")
|
||||||
|
mobkit.remember(self,"time", self.time_total)
|
||||||
|
return true
|
||||||
|
|
||||||
|
else
|
||||||
|
|
||||||
|
if remember == "0" then return true else return false end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- The Brain !
|
||||||
|
local function whale_brain(self)
|
||||||
|
|
||||||
|
if self.hp <= 0 then
|
||||||
|
mobkit.clear_queue_high(self)
|
||||||
|
water_life.handle_drops(self)
|
||||||
|
mobkit.make_sound(self,"death")
|
||||||
|
mobkit.hq_die(self)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check every 2 seconds what is under whale's belly
|
||||||
|
if mobkit.timer(self,2) then
|
||||||
|
local stand = mobkit.get_stand_pos(self)
|
||||||
|
if stand then stand.y = stand.y - 1 end
|
||||||
|
|
||||||
|
local node = mobkit.nodeatpos(stand)
|
||||||
|
if node then
|
||||||
|
if node.name ~= "default:water_source" then
|
||||||
|
mobkit.hurt(self, 20)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- big animals need to avoid obstacles
|
||||||
|
|
||||||
|
|
||||||
|
if mobkit.timer(self,1) then
|
||||||
|
local remember = mobkit.recall(self,"time")
|
||||||
|
if remember then
|
||||||
|
if self.time_total - remember > 59 then
|
||||||
|
mobkit.forget(self,"turn")
|
||||||
|
mobkit.forget(self,"time")
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local yaw = self.object:get_yaw() + pi
|
||||||
|
local pos = mobkit.get_stand_pos(self)
|
||||||
|
|
||||||
|
local spos = mobkit.pos_translate2d(pos,yaw,15)
|
||||||
|
local hpos = mobkit.pos_translate2d(pos,yaw,6)
|
||||||
|
local head = mobkit.pos_shift(hpos,{y=4})
|
||||||
|
local node = minetest.get_node(head)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
local left = mobkit.pos_shift(spos,{x=-3,y=3,z=-3})
|
||||||
|
local right = mobkit.pos_shift(spos,{x=3,y=3,z=3})
|
||||||
|
|
||||||
|
|
||||||
|
local up = mobkit.pos_shift(spos,{x=-1,y=3,z=-1})
|
||||||
|
local down = mobkit.pos_shift(spos,{x=1,y=-2,z=1})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
yaw = yaw - pi
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if node then -- anything above head ? dive.
|
||||||
|
|
||||||
|
if node.name ~= "default:water_source" and node.name ~= "air" then
|
||||||
|
local hvel = vector.multiply(vector.normalize({x=head.x,y=0,z=head.z}),4)
|
||||||
|
self.object:set_velocity({x=hvel.x,y=-1,z=hvel.z})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local vcheck= minetest.find_nodes_in_area(up,down, {"default:water_source"})
|
||||||
|
local hcheck = minetest.find_nodes_in_area(left,right, {"default:water_source"})
|
||||||
|
--minetest.chat_send_all(dump(#vcheck).." - "..dump(#hcheck))
|
||||||
|
if #vcheck < 54 or #hcheck < 49 then
|
||||||
|
--mobkit.clear_queue_high(self)
|
||||||
|
if chose_turn(self,pos,yaw) then
|
||||||
|
water_life.big_hq_aqua_turn(self,30,yaw+(pi/24),-0.5)
|
||||||
|
else
|
||||||
|
water_life.big_hq_aqua_turn(self,30,yaw-(pi/24),-0.5)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if mobkit.is_queue_empty_high(self) then water_life.big_aqua_roam(self,20,-1) end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_entity("water_life:whale",{
|
||||||
|
-- common props
|
||||||
|
physical = true,
|
||||||
|
stepheight = 0.1, --EVIL!
|
||||||
|
weight = 250,
|
||||||
|
collide_with_objects = false,
|
||||||
|
collisionbox = {-3, -2, -3, 3, 2, 3},
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "water_life_whale.b3d",
|
||||||
|
textures = {"water_life_whale.png"},
|
||||||
|
visual_size = {x = 3.5, y = 3.5},
|
||||||
|
drops = {
|
||||||
|
{name = "default:diamond", chance = 5, min = 10, max = 50,},
|
||||||
|
{name = "water_life:meat_raw", chance = 1, min = 15, max = 65,},
|
||||||
|
},
|
||||||
|
static_save = false,
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
on_step = mobkit.stepfunc, -- required
|
||||||
|
on_activate = mobkit.actfunc, -- required
|
||||||
|
get_staticdata = mobkit.statfunc,
|
||||||
|
-- api props
|
||||||
|
springiness=0,
|
||||||
|
buoyancy = 0.98, -- portion of hitbox submerged
|
||||||
|
max_speed = -1,
|
||||||
|
jump_height = 1.26,
|
||||||
|
view_range = 32,
|
||||||
|
-- lung_capacity = 0, -- seconds
|
||||||
|
max_hp = 500,
|
||||||
|
timeout=300,
|
||||||
|
attack={range=4.5,damage_groups={fleshy=15}},
|
||||||
|
sounds = {
|
||||||
|
random = "water_life_whale.ogg",
|
||||||
|
death = "water_life_whale.ogg",
|
||||||
|
distance = 10,
|
||||||
|
},
|
||||||
|
|
||||||
|
animation = {
|
||||||
|
def={range={x=1,y=59},speed=5,loop=true},
|
||||||
|
fast={range={x=1,y=59},speed=20,loop=true},
|
||||||
|
back={range={x=15,y=1},speed=7,loop=false},
|
||||||
|
},
|
||||||
|
|
||||||
|
brainfunc = whale_brain,
|
||||||
|
|
||||||
|
on_punch=function(self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||||
|
if mobkit.is_alive(self) then
|
||||||
|
local obj = self.object
|
||||||
|
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})
|
||||||
|
self.object:add_velocity({x=0,y=-5, z=0})
|
||||||
|
|
||||||
|
|
||||||
|
if time_from_last_punch > 2 then
|
||||||
|
mobkit.hurt(self,tool_capabilities.damage_groups.fleshy or 1)
|
||||||
|
else
|
||||||
|
if puncher:is_player() then
|
||||||
|
minetest.chat_send_player(puncher:get_player_name(),">>> You missed <<<")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
obj:set_nametag_attributes({
|
||||||
|
color = '#ff7373',
|
||||||
|
text = ">>> "..tostring(math.floor(self.hp/5)).."% <<<",
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user