diff options
| author | TenPlus1 <kinsellaja@yahoo.com> | 2018-06-27 09:44:00 +0100 | 
|---|---|---|
| committer | TenPlus1 <kinsellaja@yahoo.com> | 2018-06-27 09:44:00 +0100 | 
| commit | 21c52c0a871c3a9aaf05f4f0f00b906f3d4b06ee (patch) | |
| tree | 10530dd1ae43794691a45b8ebe50a8fa195552df | |
| parent | 7ed80b6a896b233c4054c50acb9720f8d5464e2d (diff) | |
better 0.4.16 comatibility and new general attack function added
| -rw-r--r-- | api.lua | 216 | ||||
| -rw-r--r-- | api.txt | 8 | 
2 files changed, 96 insertions, 128 deletions
@@ -3,7 +3,7 @@  mobs = {}  mobs.mod = "redo" -mobs.version = "20180617" +mobs.version = "20180627"  -- Intllib @@ -127,15 +127,15 @@ local set_velocity = function(self, v)  	-- do not move if mob has been ordered to stay  	if self.order == "stand" then -		self.object:setvelocity({x = 0, y = 0, z = 0}) +		self.object:set_velocity({x = 0, y = 0, z = 0})  		return  	end  	local yaw = (self.object:get_yaw() or 0) + self.rotate -	self.object:setvelocity({ +	self.object:set_velocity({  		x = sin(yaw) * -v, -		y = self.object:getvelocity().y, +		y = self.object:get_velocity().y,  		z = cos(yaw) * v  	})  end @@ -144,7 +144,7 @@ end  -- calculate mob velocity  local get_velocity = function(self) -	local v = self.object:getvelocity() +	local v = self.object:get_velocity()  	return (v.x * v.x + v.z * v.z) ^ 0.5  end @@ -411,7 +411,7 @@ local item_drop = function(self, cooked)  			if obj and obj:get_luaentity() then -				obj:setvelocity({ +				obj:set_velocity({  					x = random(-10, 10) / 9,  					y = 6,  					z = random(-10, 10) / 9, @@ -639,7 +639,7 @@ local do_env_damage = function(self)  ]]  	-- don't fall when on ignore, just stand still  	if self.standing_in == "ignore" then -		self.object:setvelocity({x = 0, y = 0, z = 0}) +		self.object:set_velocity({x = 0, y = 0, z = 0})  	end  	local nodef = minetest.registered_nodes[self.standing_in] @@ -719,7 +719,7 @@ local do_jump = function(self)  	-- something stopping us while moving?  	if self.state ~= "stand"  	and get_velocity(self) > 0.5 -	and self.object:getvelocity().y ~= 0 then +	and self.object:get_velocity().y ~= 0 then  		return false  	end @@ -761,13 +761,13 @@ local do_jump = function(self)  		if not nod.name:find("fence")  		and not nod.name:find("gate") then -			local v = self.object:getvelocity() +			local v = self.object:get_velocity()  			v.y = self.jump_height  			set_animation(self, "jump") -- only when defined -			self.object:setvelocity(v) +			self.object:set_velocity(v)  			-- when in air move forward  			minetest.after(0.3, function(self, v) @@ -879,7 +879,7 @@ local breed = function(self)  				self.on_grown(self)  			else  				-- jump when fully grown so as not to fall into ground -				self.object:setvelocity({ +				self.object:set_velocity({  					x = 0,  					y = self.jump_height,  					z = 0 @@ -1027,7 +1027,7 @@ local replace = function(self, pos)  	or not self.replace_rate  	or not self.replace_what  	or self.child == true -	or self.object:getvelocity().y ~= 0 +	or self.object:get_velocity().y ~= 0  	or random(1, self.replace_rate) > 1 then  		return  	end @@ -1283,7 +1283,7 @@ local smart_mobs = function(self, s, p, dist, dtime)  					end  					s.y = s.y - sheight -					self.object:setpos({x = s.x, y = s.y + 2, z = s.z}) +					self.object:set_pos({x = s.x, y = s.y + 2, z = s.z})  				else -- dig 2 blocks to make door toward player direction @@ -1366,114 +1366,81 @@ local specific_attack = function(list, what)  end --- monster find someone to attack -local monster_attack = function(self) +-- general attack function for all mobs ========== +local general_attack = function(self) -	if self.type ~= "monster" -	or not damage_enabled -	or creative +	-- return if already attacking, passive or docile during day +	if self.passive  	or self.state == "attack"  	or day_docile(self) then  		return  	end  	local s = self.object:get_pos() -	local p, sp, dist -	local player, obj, min_player -	local type, name = "", "" -	local min_dist = self.view_range + 1  	local objs = minetest.get_objects_inside_radius(s, self.view_range) +	-- remove entities we aren't interested in  	for n = 1, #objs do -		if objs[n]:is_player() then - -			if mobs.invis[ objs[n]:get_player_name() ] then +		local ent = objs[n]:get_luaentity() -				type = "" -			else -				player = objs[n] -				type = "player" -				name = "player" -			end -		else -			obj = objs[n]:get_luaentity() +		-- are we a player? +		if objs[n]:is_player() then -			if obj then -				player = obj.object -				type = obj.type -				name = obj.name or "" +			-- if player invisible or mob not setup to attack then remove from list +			if self.attack_players == false +			or (self.owner and self.type ~= "monster") +			or mobs.invis[objs[n]:get_player_name()] +			or not specific_attack(self.specific_attack, "player") then +				objs[n] = nil +--print("- pla", n)  			end -		end -		-- find specific mob to attack, failing that attack player/npc/animal -		if specific_attack(self.specific_attack, name) -		and (type == "player" or type == "npc" -			or (type == "animal" and self.attack_animals == true)) then +		-- or are we a mob? +		elseif ent and ent._cmi_is_mob then -			p = player:get_pos() -			sp = s - -			dist = get_distance(p, s) - -			-- aim higher to make looking up hills more realistic -			p.y = p.y + 1 -			sp.y = sp.y + 1 - - -			-- choose closest player to attack -			if dist < min_dist -			and line_of_sight(self, sp, p, 2) == true then -				min_dist = dist -				min_player = player +			-- remove mobs not to attack +			if self.name == ent.name +			or (not self.attack_animals and ent.type == "animal") +			or (not self.attack_monsters and ent.type == "monster") +			or (not self.attack_npcs and ent.type == "npc") +			or not specific_attack(self.specific_attack, ent.name) then +				objs[n] = nil +--print("- mob", n, self.name, ent.name)  			end -		end -	end -	-- attack player -	if min_player then -		do_attack(self, min_player) -	end -end - - --- npc, find closest monster to attack -local npc_attack = function(self) - -	if self.type ~= "npc" -	or not self.attacks_monsters -	or self.state == "attack" then -		return +		-- remove all other entities +		else +--print(" -obj", n) +			objs[n] = nil +		end  	end -	local p, sp, obj, min_player, dist -	local s = self.object:get_pos() +	local p, sp, dist, min_player  	local min_dist = self.view_range + 1 -	local objs = minetest.get_objects_inside_radius(s, self.view_range) -	for n = 1, #objs do +	-- go through remaining entities and select closest +	for _,player in pairs(objs) do -		obj = objs[n]:get_luaentity() +		p = player:get_pos() +		sp = s -		if obj and obj.type == "monster" then +		dist = get_distance(p, s) -			p = obj.object:get_pos() -			sp = s +		-- aim higher to make looking up hills more realistic +		p.y = p.y + 1 +		sp.y = sp.y + 1 -			dist = get_distance(p, s) - -			-- aim higher to make looking up hills more realistic -			p.y = p.y + 1 -			sp.y = sp.y + 1 - -			if dist < min_dist -			and line_of_sight(self, sp, p, 2) == true then -				min_dist = dist -				min_player = obj.object -			end +		-- choose closest player to attack that isnt self +		if dist ~= 0 +		and dist < min_dist +		and line_of_sight(self, sp, p, 2) == true then +			min_dist = dist +			min_player = player  		end  	end +	-- attack closest player or mob  	if min_player then  		do_attack(self, min_player)  	end @@ -1508,9 +1475,8 @@ local runaway_from = function(self)  	end  	local s = self.object:get_pos() -	local p, sp, dist -	local player, obj, min_player -	local type, name = "", "" +	local p, sp, dist, pname +	local player, obj, min_player, name  	local min_dist = self.view_range + 1  	local objs = minetest.get_objects_inside_radius(s, self.view_range) @@ -1518,13 +1484,14 @@ local runaway_from = function(self)  		if objs[n]:is_player() then -			if mobs.invis[ objs[n]:get_player_name() ] -			or self.owner == objs[n]:get_player_name() then +			pname = objs[n]:get_player_name() + +			if mobs.invis[pname] +			or self.owner == pname then -				type = "" +				name = ""  			else  				player = objs[n] -				type = "player"  				name = "player"  			end  		else @@ -1532,7 +1499,6 @@ local runaway_from = function(self)  			if obj then  				player = obj.object -				type = obj.type  				name = obj.name or ""  			end  		end @@ -1550,8 +1516,7 @@ local runaway_from = function(self)  			dist = get_distance(p, s) - -			-- choose closest player/mpb to runaway from +			-- choose closest player/mob to runaway from  			if dist < min_dist  			and line_of_sight(self, sp, p, 2) == true then  				min_dist = dist @@ -1688,7 +1653,7 @@ local follow_flop = function(self)  		if not flight_check(self, s) then  			self.state = "flop" -			self.object:setvelocity({x = 0, y = -5, z = 0}) +			self.object:set_velocity({x = 0, y = -5, z = 0})  			set_animation(self, "stand") @@ -1787,10 +1752,10 @@ local do_states = function(self, dtime)  				--[[ fly up/down randomly for flying mobs  				if self.fly and random(1, 100) <= self.walk_chance then -					local v = self.object:getvelocity() +					local v = self.object:get_velocity()  					local ud = random(-1, 2) / 9 -					self.object:setvelocity({x = v.x, y = ud, z = v.z}) +					self.object:set_velocity({x = v.x, y = ud, z = v.z})  				end--]]  			end  		end @@ -2057,13 +2022,13 @@ local do_states = function(self, dtime)  				local me_y = floor(p1.y)  				local p2 = p  				local p_y = floor(p2.y + 1) -				local v = self.object:getvelocity() +				local v = self.object:get_velocity()  				if flight_check(self, s) then  					if me_y < p_y then -						self.object:setvelocity({ +						self.object:set_velocity({  							x = v.x,  							y = 1 * self.walk_velocity,  							z = v.z @@ -2071,7 +2036,7 @@ local do_states = function(self, dtime)  					elseif me_y > p_y then -						self.object:setvelocity({ +						self.object:set_velocity({  							x = v.x,  							y = -1 * self.walk_velocity,  							z = v.z @@ -2080,7 +2045,7 @@ local do_states = function(self, dtime)  				else  					if me_y < p_y then -						self.object:setvelocity({ +						self.object:set_velocity({  							x = v.x,  							y = 0.01,  							z = v.z @@ -2088,7 +2053,7 @@ local do_states = function(self, dtime)  					elseif me_y > p_y then -						self.object:setvelocity({ +						self.object:set_velocity({  							x = v.x,  							y = -0.01,  							z = v.z @@ -2272,7 +2237,7 @@ local do_states = function(self, dtime)  					vec.y = vec.y * (v / amount)  					vec.z = vec.z * (v / amount) -					obj:setvelocity(vec) +					obj:set_velocity(vec)  				end  			end  		end @@ -2288,12 +2253,12 @@ local falling = function(self, pos)  	end  	-- floating in water (or falling) -	local v = self.object:getvelocity() +	local v = self.object:get_velocity()  	if v.y > 0 then  		-- apply gravity when moving up -		self.object:setacceleration({ +		self.object:set_acceleration({  			x = 0,  			y = -10,  			z = 0 @@ -2302,14 +2267,14 @@ local falling = function(self, pos)  	elseif v.y <= 0 and v.y > self.fall_speed then  		-- fall downwards at set speed -		self.object:setacceleration({ +		self.object:set_acceleration({  			x = 0,  			y = self.fall_speed,  			z = 0  		})  	else  		-- stop accelerating once max fall speed hit -		self.object:setacceleration({x = 0, y = 0, z = 0}) +		self.object:set_acceleration({x = 0, y = 0, z = 0})  	end  	-- in water then float up @@ -2317,7 +2282,7 @@ local falling = function(self, pos)  		if self.floats == 1 then -			self.object:setacceleration({ +			self.object:set_acceleration({  				x = 0,  				y = -self.fall_speed / (max(1, v.y) ^ 8), -- 8 was 2  				z = 0 @@ -2327,7 +2292,7 @@ local falling = function(self, pos)  		-- fall damage onto solid ground  		if self.fall_damage == 1 -		and self.object:getvelocity().y == 0 then +		and self.object:get_velocity().y == 0 then  			local d = (self.old_y or 0) - self.object:get_pos().y @@ -2523,7 +2488,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)  		if self.knock_back  		and tflp >= punch_interval then -			local v = self.object:getvelocity() +			local v = self.object:get_velocity()  			local r = 1.4 - min(punch_interval, 1.4)  			local kb = r * 5  			local up = 2 @@ -2544,7 +2509,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)  				kb = kb * 1.5  			end -			self.object:setvelocity({ +			self.object:set_velocity({  				x = dir.x * kb,  				y = up,  				z = dir.z * kb @@ -2583,6 +2548,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)  	if self.passive == false  	and self.state ~= "flop"  	and self.child == false +	and self.attack_players == true  	and hitter:get_player_name() ~= self.owner  	and not mobs.invis[ name ] then @@ -2598,7 +2564,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)  			obj = objs[n]:get_luaentity() -			if obj then +			if obj and obj._cmi_is_mob then  				-- only alert members of same mob  				if obj.group_attack == true @@ -2975,9 +2941,7 @@ local mob_step = function(self, dtime)  		replace(self, pos)  	end -	monster_attack(self) - -	npc_attack(self) +	general_attack(self)  	breed(self) @@ -3058,8 +3022,6 @@ minetest.register_entity(name, {  	follow = def.follow,  	jump = def.jump ~= false,  	walk_chance = def.walk_chance or 50, -	attacks_monsters = def.attacks_monsters or false, -	group_attack = def.group_attack or false,  	passive = def.passive or false,  	knock_back = def.knock_back ~= false,  	blood_amount = def.blood_amount or 5, @@ -3102,7 +3064,11 @@ minetest.register_entity(name, {  	dogshoot_count = 0,  	dogshoot_count_max = def.dogshoot_count_max or 5,  	dogshoot_count2_max = def.dogshoot_count2_max or (def.dogshoot_count_max or 5), +	group_attack = def.group_attack or false, +	attack_monsters = def.attacks_monsters or def.attack_monsters or false,  	attack_animals = def.attack_animals or false, +	attack_players = def.attack_players ~= false, +	attack_npcs = def.attack_npcs ~= false,  	specific_attack = def.specific_attack,  	runaway_from = def.runaway_from,  	owner_loyal = def.owner_loyal, @@ -71,9 +71,11 @@ functions needed for the mob to work properly which contains the following:     'docile_by_day'       when true has mobs wandering around during daylight                           hours and only attacking player at night or when                           provoked. -   'attacks_monsters'    when true has npc's attacking monsters or not. -   'attack_animals'      when true will have monsters attacking animals. -   'owner_loyal'         when true will have tamed mobs attack anything player +   'attack_monsters'     when true mob will attack monsters. +   'attack_animals'      when true mob will attack animals. +   'attack_npcs'         when true mob will attack npcs within range. +   'attack_players'      when true mob will attack players nearby. +   'owner_loyal'         when true non-docile tamed mobs attack anything player                           punches when nearby.     'group_attack'        when true has same mob type grouping together to attack                           offender.  | 
