diff options
| author | TenPlus1 <kinsellaja@yahoo.com> | 2017-01-17 14:14:12 +0000 | 
|---|---|---|
| committer | TenPlus1 <kinsellaja@yahoo.com> | 2017-01-17 14:14:12 +0000 | 
| commit | 2ee53fe66058a5c33b509c1796e43afb8d70fb7e (patch) | |
| tree | 7ccf351f48f7f302a22bb75f6949c8408d398940 | |
| parent | 4bcfa6b802fe389535dbc62522df9dba37e7c467 (diff) | |
new line_of_sight function by BrunoMine and flight_check by taikedz
| -rw-r--r-- | api.lua | 129 | 
1 files changed, 110 insertions, 19 deletions
@@ -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)  | 
