summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTenPlus1 <kinsellaja@yahoo.com>2017-01-17 14:14:12 +0000
committerTenPlus1 <kinsellaja@yahoo.com>2017-01-17 14:14:12 +0000
commit2ee53fe66058a5c33b509c1796e43afb8d70fb7e (patch)
tree7ccf351f48f7f302a22bb75f6949c8408d398940
parent4bcfa6b802fe389535dbc62522df9dba37e7c467 (diff)
new line_of_sight function by BrunoMine and flight_check by taikedz
-rw-r--r--api.lua129
1 files changed, 110 insertions, 19 deletions
diff --git a/api.lua b/api.lua
index 2336cfa..7d96090 100644
--- a/api.lua
+++ b/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,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)