a-planet-alive/my_changes/mobs/mobs_mobkit/water_life/files/api.lua

901 lines
26 KiB
Lua

local abs = math.abs
local pi = math.pi
local floor = math.floor
local ceil = math.ceil
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 rad = math.rad
local deg=math.deg
local tan = math.tan
local cos = math.cos
local atan=math.atan
local neighbors ={
{x=1,z=0},
{x=1,z=1},
{x=0,z=1},
{x=-1,z=1},
{x=-1,z=0},
{x=-1,z=-1},
{x=0,z=-1},
{x=1,z=-1}
}
-- pseudo random generator, init and call function
water_life.randomtable = PcgRandom(math.random(2^23)+1)
function water_life.random(min,max)
if not min and not max then return math.abs(water_life.randomtable:next() / 2^31) end
if not max then
max = min
min = 1
end
if max and not min then min = 1 end
if max < min then return water_life.randomtable:next(max,min) end
return water_life.randomtable:next(min,max)
end
--
local random = water_life.random -- do not delete, this MUST be here!
--
--checks if entity is in a small water pool
function water_life.check_for_pool(self,deep,minr,pos)
if not self and not pos then return nil end
if not deep then deep = 3 end
if not minr then minr = 3 end
local max = 16
if not pos then
pos = self.object:get_pos()
end
local d,t,s = water_life.water_depth(pos,max)
if not d then return nil end
local cpos = {}
local ispool = 0
for i = 0,270,90 do
cpos = mobkit.pos_translate2d(pos,rad(i),minr)
if water_life.find_collision(pos,cpos,false) then ispool = ispool + 1 end
end
if ispool > 2 and d < deep then return true end
return false
end
-- returns ingame time, 1 = morning, 2 = noon, 3 = afternoon, 4 = night
function water_life.get_game_time()
local time = minetest.get_timeofday()
local hour = math.floor(time*24)
if hour >= 5 and hour < 10 then return 1 end
if hour >= 10 and hour < 15 then return 2 end
if hour >= 15 and hour < 20 then return 3 end
if hour > 20 or hour < 5 then return 4 end
end
function water_life_get_biome_data(pos)
if not pos then return nil end
local table = minetest.get_biome_data(pos)
if not table then return nil end
local biome = {}
biome.id = table.biome
biome.name = minetest.get_biome_name(table.biome)
biome.temp = math.floor((table.heat-32)*5/9) --turn fahrenheit into celsius
biome.humid = math.floor(table.humidity*100)/100
return biome
end
-- returns closest enemy or player, if player is true enemies must be in entity definition: predators = {[name1]=1,[name2]=1,.....}
function water_life.get_closest_enemy(self,player)
local cobj = nil
local dist = water_life.abr*64
local pos = self.object:get_pos()
local otable = minetest.get_objects_inside_radius(pos, self.view_range)
if not self.predators and not player then return nil end
for _,obj in ipairs(otable) do
local luaent = obj:get_luaentity()
if mobkit.is_alive(obj) and not obj:is_player() and luaent and self.predators[luaent.name] then
local opos = obj:get_pos()
local odist = abs(opos.x-pos.x) + abs(opos.z-pos.z)
if odist < dist then
dist=odist
cobj=obj
end
elseif mobkit.is_alive(obj) and obj:is_player() and player then
local opos = obj:get_pos()
local odist = abs(opos.x-pos.x) + abs(opos.z-pos.z)
if odist < dist then
dist=odist
cobj=obj
end
end
end
return cobj
end
--player knockback from entity
function water_life.knockback_player(self,target,force)
if not target:is_player() then return end
if not self.object then return end
if not force then force = 10 end
local dir = minetest.yaw_to_dir(self.object:get_yaw())
dir = vector.multiply(dir, force)
dir = {x=dir.x, y=dir.y+force/2, z= dir.z}
target:add_player_velocity(dir)
end
--sets an urchin somewhere but not in the center of a node
function water_life.set_urchin(pos,name)
if not pos then return end
if not name then name = "water_life:urchin" end
local x = random()/2
local z = random()/2
if water_life.leftorright() then pos.x = pos.x +x else pos.x=pos.x - x end
if water_life.leftorright() then pos.z = pos.z +z else pos.z=pos.z - z end
local obj = minetest.add_entity(pos, name)
return obj
end
-- add vector cross function for flying behavior if not yet there
if vector and not vector.cross then
function vector.cross(a, b)
return {
x = a.y * b.z - a.z * b.y,
y = a.z * b.x - a.x * b.z,
z = a.x * b.y - a.y * b.x
}
end
end
-- show temp marker
function water_life.temp_show(pos,time,pillar)
if not pos then return end
if not time then time = 5 end
local step = 1
if not pillar then pillar = 1 end
if pillar < 0 then step = -1 end
for i = 1,pillar,step do
local obj = minetest.add_entity({x=pos.x, y=pos.y+i, z=pos.z}, "water_life:pos")
if obj then
minetest.after(time, function(obj) obj:remove() end, obj)
end
end
end
-- throws a coin
function water_life.leftorright()
local rnd = random()
if rnd > 0.5 then return true else return false end
end
-- distance from self to target
function water_life.dist2tgt(self,tgt)
local pos = mobkit.get_stand_pos(self)
local tpos = tgt:get_pos()
return vector.distance(pos,tpos)
end
function water_life.dumbstep(self,height,tpos,speed_factor,idle_duration)
if height <= 0.001 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)
end
idle_duration = idle_duration or 6
mobkit.lq_idle(self,random(ceil(idle_duration*0.5),idle_duration))
end
-- drop on death what is definded in the entity table
function water_life.handle_drops(self)
if not self.drops then return end
for _,item in ipairs(self.drops) do
local amount = random (item.min, item.max)
local chance = random(1,100)
local pos = self.object:get_pos()
pos.y = pos.y + self.collisionbox[5] +1
if chance < (100/item.chance) then
local obj = minetest.add_item(pos, item.name.." "..tostring(amount))
end
end
end
function water_life.register_shark_food(name)
table.insert(water_life.shark_food,name)
end
function water_life.register_gull_bait(name)
if name then water_life.gull_bait[name] = 1 end
end
function water_life.feed_shark(self)
for i = 1,#water_life.shark_food,1 do
if water_life.shark_food[i] ~= "water_life:fish" and water_life.shark_food[i] ~= "water_life:fish_tamed" then
local target = mobkit.get_closest_entity(self,water_life.shark_food[i])
if target then
return target
end
end
end
return nil
end
function water_life.get_close_drops(self,name)
local objs = minetest.get_objects_inside_radius(self.object:get_pos(), self.view_range)
if #objs < 1 then return nil end
for i = #objs,1,-1 do
local entity = objs[i]:get_luaentity()
if not entity or not entity.name == "__builtin:item" then table.remove(objs,i) end -- remove any entity different from a drop
end
if #objs < 1 then return nil end
if not name then return objs[random(#objs)] end -- no name, return random drop
for i=#objs,1,-1 do
local entity = objs[i]:get_luaentity()
if not entity.itemstring then
table.remove(objs,i)
else
if not string.match(entity.itemstring,name) then table.remove(objs,i) end -- remove anything different from name
end
end
if #objs < 1 then
return nil
else
return objs[random(#objs)]
end
end
function water_life.inwater(obj)
if not obj then return nil end
local pos = obj:get_pos()
local node = minetest.get_node(pos)
if not node or node.name == 'ignore' then return nil end
if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes
local type = minetest.registered_nodes[node.name]["liquidtype"]
if type == "none" then return nil end
return true
end
function water_life.aqua_radar_dumb(pos,yaw,range,reverse,shallow) -- same as mobkit's but added shallow water if true
range = range or 4
local function okpos(p)
local node = mobkit.nodeatpos(p)
if node then
if node.drawtype == 'liquid' then
local nodeu = mobkit.nodeatpos(mobkit.pos_shift(p,{y=1}))
local noded = mobkit.nodeatpos(mobkit.pos_shift(p,{y=-1}))
if ((nodeu and nodeu.drawtype == 'liquid') or (noded and noded.drawtype == 'liquid')) or shallow then
return true
else
return false
end
else
local h,l = mobkit.get_terrain_height(p)
if h then
local node2 = mobkit.nodeatpos({x=p.x,y=h+1.99,z=p.z})
if node2 and node2.drawtype == 'liquid' then return true, h end
else
return false
end
end
else
return false
end
end
local fpos = mobkit.pos_translate2d(pos,yaw,range)
local ok,h = okpos(fpos)
if not ok then
local ffrom, fto, fstep
if reverse then
ffrom, fto, fstep = 3,1,-1
else
ffrom, fto, fstep = 1,3,1
end
for i=ffrom, fto, fstep do
local ok,h = okpos(mobkit.pos_translate2d(pos,yaw+i,range))
if ok then return yaw+i,h end
ok,h = okpos(mobkit.pos_translate2d(pos,yaw-i,range))
if ok then return yaw-i,h end
end
return yaw+pi,h
else
return yaw, h
end
end
-- counts animals in specified radius or active_block_range, returns a table containing numbers
function water_life.count_objects(pos,radius,name)
if not radius then radius = water_life.abr * 16 end
local all_objects = minetest.get_objects_inside_radius(pos, radius)
local hasil = {}
hasil.whales = 0
hasil.sharks = 0
hasil.fish = 0
hasil.name = 0
hasil.all = #all_objects or 0
local _,obj
for _,obj in ipairs(all_objects) do
local entity = obj:get_luaentity()
if name then
if entity and entity.name == name then
hasil.name = hasil.name +1
end
end
if entity and entity.name == "water_life:whale" then
hasil.whales = hasil.whales +1
elseif entity and entity.name == "water_life:shark" then
hasil.sharks = hasil.sharks +1
elseif entity and (entity.name == "water_life:fish" or entity.name == "water_life:fish_tamed") then
hasil.fish = hasil.fish +1
end
if entity and entity.name then
if not hasil[entity.name] then
hasil[entity.name] = 1
else
hasil[entity.name] = hasil[entity.name] +1
end
end
end
return hasil
end
function water_life.get_herd_members(self,radius)
local pos = mobkit.get_stand_pos(self)
local name = self.name
if not radius then radius = water_life.abo * 16 end
local all_objects = minetest.get_objects_inside_radius(pos, radius)
if #all_objects < 1 then return nil end
for i = #all_objects,1,-1 do
local entity = all_objects[i]:get_luaentity()
if entity and entity.name ~= name then
table.remove(all_objects,i)
end
end
if #all_objects < 1 then
return nil
else
return all_objects
end
end
-- returns 2D angle from self to target in radians
function water_life.get_yaw_to_object(self,target)
local pos = mobkit.get_stand_pos(self)
local tpos = target:get_pos()
local tyaw = minetest.dir_to_yaw(vector.direction(pos, tpos))
return tyaw
end
-- returns 2D angle from self to pos in radians
function water_life.get_yaw_to_pos(self,tpos)
local pos = mobkit.get_stand_pos(self)
local tyaw = minetest.dir_to_yaw(vector.direction(pos, tpos))
return tyaw
end
function water_life.isinliquid(target)
if not target then return false end
local nodepos = mobkit.get_stand_pos(target)
local node1 = mobkit.nodeatpos(nodepos)
nodepos.y = nodepos.y -1
local node2 = mobkit.nodeatpos(nodepos)
if node1 and node1.drawtype=='liquid' or (node2 and node2.drawtype=='liquid' and node1 and node1.drawtype=='airlike') then
return true
end
end
-- find if there is a node between pos1 and pos2
-- water = true means water = obstacle
-- returns distance to obstacle in nodes or nil
function water_life.find_collision(pos1,pos2,water,objects)
local ray = minetest.raycast(pos1, pos2, objects, water)
for pointed_thing in ray do
if pointed_thing.type == "node" then
local dist = math.floor(vector.distance(pos1,pointed_thing.under))
return dist
end
end
return nil
end
-- fast radar, less accurate
-- yaw-x to the right, yaw + x to the left !
-- sonar = true water is no obstacle
function water_life.radar_fast(self,dist,sonar)
local water = not sonar
if not dist then dist = self.view_range end
local angel = atan(3/dist)
local yaw = self.object:get_yaw()
local tpos = self.object:get_pos()
local tapos = mobkit.pos_translate2d(tpos,(yaw-angel),dist)
local tbpos = mobkit.pos_translate2d(tpos,yaw,dist)
local tcpos = mobkit.pos_translate2d(tpos,(yaw+angel),dist)
local tupos = mobkit.pos_shift(tbpos,{y=2})
local tdpos = mobkit.pos_shift(tbpos,{y=-2})
local right = water_life.find_collision(tpos,tapos,water)
local left = water_life.find_collision(tpos,tcpos,water)
local center = water_life.find_collision(tpos,tbpos,water)
local up = water_life.find_collision(tpos,tupos,water)
local down = water_life.find_collision(tpos,tdpos,water)
return left,right,center,up,down
end
-- WIP radar, not ready to use !
function water_life.radar_fast_cols(obj,dist,sonar,rev) --sonar = true, water no obstacle :: rev = true array contains possible positions
if not dist then dist = 3 end
local pos = obj:get_pos()
local yaw = 0
local box = {}
local counter = 1
local rarray = {}
if obj:is_player() then
yaw = obj:get_look_horizontal()
box = obj:get_properties().collisionbox
else
yaw = obj:get_yaw()
if obj:get_luaentity().name == "water_life:whale" then yaw = yaw + rad(180) end
box = obj:get_luaentity().collisionbox
end
local vec = minetest.yaw_to_dir(yaw)
local crasha = mobkit.get_box_displace_cols(pos,box,vec,dist)
if crasha then
for i = #crasha,1,-1 do
for j = #crasha[i],1,-1 do
local cpos ={x=crasha[i][j].x, y= pos.y, z= crasha[i][j].z}
--local cyaw = abs(math.floor(minetest.dir_to_yaw(vector.direction(pos,cpos))*10))
local node = minetest.get_node(cpos)
if minetest.registered_nodes[node.name] then
local kill = false
if minetest.registered_nodes[node.name]["drawtype"] == "airlike" then kill = true end
if minetest.registered_nodes[node.name]["buildable_to"] then kill = true end
if minetest.registered_nodes[node.name]["drawtype"] == "liquid" then kill = sonar end
if kill then
if not rev then
table.remove(crasha[i],j)
else
rarray[counter] = cpos
counter = counter +1
end
else
if not rev then
rarray[counter] = cpos
counter = counter +1
else
table.remove(crasha[i],j)
end
end
end
end
end
end
return rarray
end
-- radar function for obstacles lying in front of an entity
-- use water = true if water should be an obstacle
function water_life.radar(pos, yaw, radius, water,fast)
if not radius or radius < 1 then radius = 16 end
local left = 0
local right = 0
if not water then water = false end
for j = 0,3,1 do
for i = 0,4,1 do
local pos2 = mobkit.pos_translate2d(pos,yaw+(i*pi/16),radius)
local pos3 = mobkit.pos_translate2d(pos,yaw-(i*pi/16),radius)
--minetest.set_node(pos2,{name="default:stone"})
if water_life.find_collision(pos,{x=pos2.x, y=pos2.y + j*2, z=pos2.z}, water) then
left = left + 5 - i
end
if water_life.find_collision(pos,{x=pos3.x, y=pos3.y + j*2, z=pos3.z},water) then
right = right + 5 - i
end
end
end
local up =0
local down = 0
if not fast then
for j = -4,4,1 do
for i = -3,3,1 do
local k = i
local pos2 = mobkit.pos_translate2d(pos,yaw+(i*pi/16),radius)
local collide = water_life.find_collision(pos,{x=pos2.x, y=pos2.y + j, z=pos2.z}, water)
if k < 0 then k = k * -1 end
if collide and j <= 0 then
down = down + math.floor((7+j-k)*collide/radius*2)
elseif collide and j >= 0 then
up = up + math.floor((7-j-k)*collide/radius*2)
end
end
end
end
local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - radius, z=pos.z}, water)
if not under then under = radius end
local above = water_life.find_collision(pos,{x=pos.x, y=pos.y + radius, z=pos.z}, water)
if not above then above = radius end
if water_life.radar_debug then
-- minetest.chat_send_all(dump(water_life.radar_debug).." left = "..left.." right = "..right.." up = "..up.." down = "..down.." under = "..under.." above = "..above)
end
return left, right, up, down, under, above
end
--find a spawn position under air
function water_life.find_node_under_air(pos,radius,name)
if not pos then return nil end
if not radius then radius = 3 end
if not name then name={"group:crumbly","group:stone","group:tree"} end
local pos1 = {x=pos.x-radius, y=pos.y-radius, z=pos.z-radius} --mobkit.pos_shift(pos,{x=radius*-1,y=radius*-1,z=radius*-1})
local pos2 = {x=pos.x+radius, y=pos.y+radius, z=pos.z+radius} --mobkit.pos_shift(pos,{x=radius,y=radius,z=radius})
local spawner = minetest.find_nodes_in_area_under_air(pos1, pos2, name)
if not spawner or #spawner < 1 then
return nil
else
local rpos = spawner[random(#spawner)]
rpos = mobkit.pos_shift(rpos,{y=1})
return rpos
end
end
-- function to find liquid surface and depth at that position
function water_life.water_depth(pos,max)
local surface = {}
local depth = 0
local type = ""
if not max then max = 10 end
if not pos then return nil end
local tempos = {}
local node = minetest.get_node(pos)
if not node or node.name == 'ignore' then return nil end
if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes
local type = minetest.registered_nodes[node.name]["liquidtype"]
local found = false
--minetest.chat_send_all(">>>"..dump(node.name).." <<<")
if type == "none" then -- start in none liquid try to find surface
local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - max, z=pos.z}, true)
--minetest.chat_send_all(dump(under).." "..dump(node.name))
if under then
local check = {x=pos.x, y=pos.y - under-1, z=pos.z}
local cname = minetest.get_node(check).name
if not minetest.registered_nodes[cname] then return nil end -- handle unknown nodes
if minetest.registered_nodes[cname]["liquidtype"] == "source" then
surface = check
found = true
end
end
if not found then
return nil
end
else -- start in liquid find way up first
local lastpos = pos
for i = 1,max,1 do
tempos = {x=pos.x, y=pos.y+i, z= pos.z}
node = minetest.get_node(tempos)
if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes
local ctype = minetest.registered_nodes[node.name]["liquidtype"]
if ctype == "none" then
surface = lastpos
found = true
break
end
lastpos = tempos
end
if not found then surface = lastpos end
end
pos = surface
type = minetest.get_node(pos).name or ""
local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - max, z=pos.z}, false)
depth = under or max
return depth, type, surface
end
-- amphibious version of mobkit
function water_life.get_next_waypoint_fast(self,tpos,nogopos)
local pos = mobkit.get_stand_pos(self)
local dir=vector.direction(pos,tpos)
local neighbor = mobkit.dir2neighbor(dir)
local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
local heightr = nil
local heightl = nil
local liq = nil
if height then
local fast = false
heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1))
if heightl and abs(heightl-height)<0.001 then
heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1))
if heightr and abs(heightr-height)<0.001 then
fast = true
dir.y = 0
local dirn = vector.normalize(dir)
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
end
end
return height, pos2, fast
else
for i=1,4 do
-- scan left
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i))
if height then return height,pos2 end
-- scan right
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i))
if height then return height,pos2 end
end
end
end
-- amphibious version of mobkit
function water_life.goto_next_waypoint(self,tpos)
local height, pos2 = water_life.get_next_waypoint_fast(self,tpos)
if not height then return false end
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 abs(tyaw-yaw) > 1 then
mobkit.lq_turn2pos(self,pos2)
end
mobkit.lq_dumbwalk(self,pos2)
else
mobkit.lq_turn2pos(self,pos2)
mobkit.lq_dumbjump(self,height)
end
return true
end
function water_life.get_next_waypoint(self,tpos)
local pos = mobkit.get_stand_pos(self)
local dir=vector.direction(pos,tpos)
local neighbor = mobkit.dir2neighbor(dir)
local function update_pos_history(self,pos)
table.insert(self.pos_history,1,pos)
if #self.pos_history > 2 then table.remove(self.pos_history,#self.pos_history) end
end
local nogopos = self.pos_history[2]
local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor)
--minetest.chat_send_all('pos2 ' .. minetest.serialize(pos2))
--minetest.chat_send_all('nogopos ' .. minetest.serialize(nogopos))
if height and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
local heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1))
if heightl and abs(heightl-height)<0.001 then
local heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1))
if heightr and abs(heightr-height)<0.001 then
dir.y = 0
local dirn = vector.normalize(dir)
local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor]))
local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z)
pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor})
end
end
update_pos_history(self,pos2)
return height, pos2
else
for i=1,3 do
-- scan left
local height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i*self.path_dir))
if height and not liq
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
update_pos_history(self,pos2)
return height,pos2
end
-- scan right
height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i*self.path_dir))
if height and not liq
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
update_pos_history(self,pos2)
return height,pos2
end
end
--scan rear
height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,4))
if height and not liquidflag
and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then
update_pos_history(self,pos2)
return height,pos2
end
end
-- stuck condition here
table.remove(self.pos_history,2)
self.path_dir = self.path_dir*-1 -- subtle change in pathfinding
end
-- blood effects
function water_life.spilltheblood(object,size)
if not water_life.bloody then return end
if not size then size = 1 end
local particlespawner_id = minetest.add_particlespawner({
amount = 50,
time = 1,
minpos = vector.new(-0.3, size/2, -0.3),
maxpos = vector.new( 0.3, size, 0.3),
minvel = {x = -1, y = 0, z = -1},
maxvel = {x = 1, y = 1, z = 1},
minacc = {x = 0, y = 2, z = 0},
maxacc = {x = 0, y = 3, z = 0},
minexptime = 0.5,
maxexptime = 1,
minsize = 1,
maxsize = 2,
texture = "water_life_bloodeffect1.png",
collisiondetection = true,
collision_removal = true,
object_collision = true,
attached = object,
})
end
-- Entity definitions
-- entity for showing positions in debug
minetest.register_entity("water_life:pos", {
initial_properties = {
visual = "cube",
collide_with_objects = false,
visual_size = {x=1.1, y=1.1},
textures = {"water_life_pos.png", "water_life_pos.png",
"water_life_pos.png", "water_life_pos.png",
"water_life_pos.png", "water_life_pos.png"},
collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55},
physical = false,
}
})
if water_life.radar_debug then
minetest.register_on_player_hpchange(function(player, hp_change, reason)
if not player or hp_change >= 0 then return hp_change end
local name = player:get_player_name()
local privs = minetest.get_player_privs(name)
if not privs.god then return hp_change end
return 0
end, true)
minetest.register_privilege("god", {description ="unvulnerable"})
end
--check here for antiserum group of eaten food
minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing)
if not user or not user:is_player() then return end
if not itemstack then return end
local name = user:get_player_name()
local antiserum = itemstack:get_definition().groups.antiserum
if antiserum then
local meta = user:get_meta()
local score = user:get_hp()
if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) hunger_ng.set_effect(user:get_player_name(), "heal", "enabled") end
water_life.change_hud(user,"poison",0)
end
return
end)
--new players are immune to snakepoison
minetest.register_on_newplayer(function(player)
if not player or not player:is_player() then return end
local meta = player:get_meta()
local join = os.time()
meta:set_int("jointime",join)
end)
-- but not forever
minetest.register_on_joinplayer(function(player)
if not player or not player:is_player() then return end
local meta = player:get_meta()
meta:set_int("bitten",0)
meta:set_int("repellant",0)
end)