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 = {}
|
||||||
mobs.mod = "redo"
|
mobs.mod = "redo"
|
||||||
|
@ -208,6 +208,96 @@ set_animation = function(self, type)
|
||||||
end
|
end
|
||||||
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
|
-- check line of sight for walkers and swimmers alike
|
||||||
function line_of_sight_water(self, pos1, pos2, stepsize)
|
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
|
-- just incase we have a special node for flying/swimming mobs
|
||||||
elseif s == false
|
elseif s == false
|
||||||
and self.fly
|
and self.fly
|
||||||
and self.fly_in then
|
and flight_check(self, pos_w) then
|
||||||
|
|
||||||
local nod = minetest.get_node(pos_w).name
|
|
||||||
|
|
||||||
if nod == self.fly_in then
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
|
|
||||||
|
@ -1063,7 +1148,8 @@ local monster_attack = function(self)
|
||||||
-- field of view check goes here
|
-- field of view check goes here
|
||||||
|
|
||||||
-- choose closest player to attack
|
-- 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
|
and dist < min_dist then
|
||||||
min_dist = dist
|
min_dist = dist
|
||||||
min_player = player
|
min_player = player
|
||||||
|
@ -1222,10 +1308,10 @@ local follow_flop = function(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- water swimmers flop when on land
|
-- swimmers flop when out of their element, and swim again when back in
|
||||||
if self.fly
|
if self.fly then
|
||||||
and self.fly_in == "default:water_source"
|
local s = self.object:getpos()
|
||||||
and self.standing_in ~= self.fly_in then
|
if not flight_check(self, s) then
|
||||||
|
|
||||||
self.state = "flop"
|
self.state = "flop"
|
||||||
self.object:setvelocity({x = 0, y = -5, z = 0})
|
self.object:setvelocity({x = 0, y = -5, z = 0})
|
||||||
|
@ -1233,6 +1319,9 @@ local follow_flop = function(self)
|
||||||
set_animation(self, "stand")
|
set_animation(self, "stand")
|
||||||
|
|
||||||
return
|
return
|
||||||
|
elseif self.state == "flop" then
|
||||||
|
self.state = "stand"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1554,7 +1643,8 @@ local do_states = function(self, dtime)
|
||||||
local p_y = floor(p2.y + 1)
|
local p_y = floor(p2.y + 1)
|
||||||
local v = self.object:getvelocity()
|
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
|
if me_y < p_y then
|
||||||
|
|
||||||
|
@ -1692,7 +1782,8 @@ local do_states = function(self, dtime)
|
||||||
p2.y = p2.y + .5--1.5
|
p2.y = p2.y + .5--1.5
|
||||||
s2.y = s2.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
|
-- play attack sound
|
||||||
mob_sound(self, self.sounds.attack)
|
mob_sound(self, self.sounds.attack)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user