forked from mtcontrib/mobs_redo
new line_of_sight function by BrunoMine and flight_check by taikedz
This commit is contained in:
parent
4bcfa6b802
commit
2ee53fe660
119
api.lua
119
api.lua
|
@ -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,14 +325,9 @@ 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
|
||||
and flight_check(self, pos_w) then
|
||||
return true
|
||||
end
|
||||
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,10 +1308,10 @@ 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})
|
||||
|
@ -1233,6 +1319,9 @@ local follow_flop = function(self)
|
|||
set_animation(self, "stand")
|
||||
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue
Block a user