new line_of_sight function by BrunoMine and flight_check by taikedz

This commit is contained in:
TenPlus1 2017-01-17 14:14:12 +00:00
parent 4bcfa6b802
commit 2ee53fe660

129
api.lua
View File

@ -1,5 +1,5 @@
-- Mobs Api (7th January 2017)
-- Mobs Api (17th January 2017)
mobs = {}
mobs.mod = "redo"
@ -208,6 +208,96 @@ set_animation = function(self, type)
end
end
-- Get distance
local get_distance = function(a, b)
local x, y, z = a.x - b.x, a.y - b.y, a.z - b.z
return square(x * x + y * y + z * z)
end
-- check line of sight (BrunoMine)
function line_of_sight(self, pos1, pos2, stepsize)
stepsize = stepsize or 1
local s, pos = minetest.line_of_sight(pos1, pos2, stepsize)
-- normal walking and flying mobs can see you through air
if s == true then
return true
end
-- New pos1 to be analyzed
local npos1 = {x = pos1.x, y = pos1.y, z = pos1.z}
local r, pos = minetest.line_of_sight(npos1, pos2, stepsize)
-- Checks the return
if r == true then return true end
-- Nodename found
local nn = minetest.get_node(pos).name
-- Target Distance (td) to travel
local td = get_distance(pos1, pos2)
-- Actual Distance (ad) traveled
local ad = 0
-- It continues to advance in the line of sight in search of a real obstruction.
while minetest.registered_nodes[nn]
and minetest.registered_nodes[nn].walkable == false do
-- Check if you can still move forward
if td < ad + stepsize then
return true -- Reached the target
end
-- Moves the analyzed pos
local d = get_distance(pos1, pos2)
npos1.x = ((pos2.x - pos1.x) / d * stepsize) + pos1.x
npos1.y = ((pos2.y - pos1.y) / d * stepsize) + pos1.y
npos1.z = ((pos2.z - pos1.z) / d * stepsize) + pos1.z
ad = ad + stepsize
-- scan again
r, pos = minetest.line_of_sight(npos1, pos2, stepsize)
if r == true then return true end
-- New Nodename found
nn = minetest.get_node(pos).name
end
return false
end
-- are we flying in what we are suppose to? (taikedz)
local function flight_check(self, pos_w)
local nod = minetest.get_node(pos_w).name
if type(self.fly_in) == "string"
and ( nod == self.fly_in or nod == self.fly_in:gsub("_source", "_flowing") ) then
return true
elseif type(self.fly_in) == "table" then
for _,fly_in in pairs(self.fly_in) do
if nod == fly_in or nod == fly_in:gsub("_source", "_flowing") then
return true
end
end
end
end
-- check line of sight for walkers and swimmers alike
function line_of_sight_water(self, pos1, pos2, stepsize)
@ -235,13 +325,8 @@ function line_of_sight_water(self, pos1, pos2, stepsize)
-- just incase we have a special node for flying/swimming mobs
elseif s == false
and self.fly
and self.fly_in then
local nod = minetest.get_node(pos_w).name
if nod == self.fly_in then
return true
end
and flight_check(self, pos_w) then
return true
end
return false
@ -1063,7 +1148,8 @@ local monster_attack = function(self)
-- field of view check goes here
-- choose closest player to attack
if line_of_sight_water(self, sp, p, 2) == true
-- if line_of_sight_water(self, sp, p, 2) == true
if line_of_sight(self, sp, p, 2) == true
and dist < min_dist then
min_dist = dist
min_player = player
@ -1222,17 +1308,20 @@ local follow_flop = function(self)
end
end
-- water swimmers flop when on land
if self.fly
and self.fly_in == "default:water_source"
and self.standing_in ~= self.fly_in then
-- swimmers flop when out of their element, and swim again when back in
if self.fly then
local s = self.object:getpos()
if not flight_check(self, s) then
self.state = "flop"
self.object:setvelocity({x = 0, y = -5, z = 0})
self.state = "flop"
self.object:setvelocity({x = 0, y = -5, z = 0})
set_animation(self, "stand")
set_animation(self, "stand")
return
return
elseif self.state == "flop" then
self.state = "stand"
end
end
end
@ -1554,7 +1643,8 @@ local do_states = function(self, dtime)
local p_y = floor(p2.y + 1)
local v = self.object:getvelocity()
if nod.name == self.fly_in then
-- if nod.name == self.fly_in then
if flight_check(self, s) then
if me_y < p_y then
@ -1692,7 +1782,8 @@ local do_states = function(self, dtime)
p2.y = p2.y + .5--1.5
s2.y = s2.y + .5--1.5
if line_of_sight_water(self, p2, s2) == true then
-- if line_of_sight_water(self, p2, s2) == true then
if line_of_sight(self, p2, s2) == true then
-- play attack sound
mob_sound(self, self.sounds.attack)