forked from nalc/spears
		
	Version 2.4
This commit is contained in:
		| @@ -5,3 +5,11 @@ DISABLE_BRONZE_SPEAR = false | ||||
| DISABLE_DIAMOND_SPEAR = false | ||||
| DISABLE_OBSIDIAN_SPEAR = false | ||||
| DISABLE_GOLD_SPEAR = false | ||||
| SPEARS_THROW_SPEED = 13 | ||||
| SPEARS_V_ZERO = {x = 0, y = 0, z = 0} | ||||
| SPEARS_DRAG_COEFF = 0.1 | ||||
| SPEARS_NODE_UNKNOWN = nil | ||||
| SPEARS_NODE_THROUGH = 0 | ||||
| SPEARS_NODE_STICKY = 1 | ||||
| SPEARS_NODE_CRACKY = 2 | ||||
| SPEARS_NODE_CRACKY_LIMIT = 3 | ||||
|   | ||||
							
								
								
									
										120
									
								
								functions.lua
									
									
									
									
									
								
							
							
						
						
									
										120
									
								
								functions.lua
									
									
									
									
									
								
							| @@ -7,19 +7,27 @@ function spears_throw (itemstack, player, pointed_thing) | ||||
| 	local pitch = player:get_look_vertical() | ||||
| 	local yaw = player:get_look_horizontal() | ||||
| 	local rotation = vector.new(0, yaw + math.pi/2, pitch + math.pi/6) | ||||
| 	-- Stick into node | ||||
| 	if pointed_thing.type == "node" then | ||||
| 		local node = minetest.get_node(pointed_thing.under) | ||||
| 		if minetest.registered_nodes[node.name].walkable and vector.distance(pointed_thing.above, throw_pos) < 1 then | ||||
| 			local spear_object = minetest.add_entity(vector.divide(vector.add(vector.multiply(pointed_thing.above, 2), pointed_thing.under), 3), spear) | ||||
| 	local wear = itemstack:get_wear() | ||||
| 	local pointed_a = pointed_thing.above | ||||
| 	local pointed_b = pointed_thing.under	 | ||||
| 	if pointed_thing.type == "node" and vector.distance(pointed_a, throw_pos) < 1 then -- Stick into node | ||||
| 		local node = minetest.get_node(pointed_b) | ||||
| 		local check_node = spears_check_node(node.name) | ||||
| 		if check_node == SPEARS_NODE_UNKNOWN then | ||||
| 			return false | ||||
| 		elseif check_node == SPEARS_NODE_CRACKY then | ||||
| 			minetest.sound_play("default_metal_footstep", {pos = pointed_a}, true) | ||||
| 			return false | ||||
| 		elseif check_node == SPEARS_NODE_STICKY then | ||||
| 			local spear_object = minetest.add_entity(vector.divide(vector.add(vector.multiply(pointed_a, 2), pointed_b), 3), spear) | ||||
| 			spear_object:set_rotation(rotation) | ||||
| 			spear_object:get_luaentity()._wear = itemstack:get_wear() | ||||
| 			spear_object:get_luaentity()._stickpos = pointed_thing.under | ||||
| 			return | ||||
| 			spear_object:get_luaentity()._wear = wear | ||||
| 			spear_object:get_luaentity()._stickpos = pointed_b | ||||
| 			minetest.sound_play("default_place_node", {pos = pointed_a}, true) | ||||
| 			return false | ||||
| 		end | ||||
| 	end | ||||
| 	-- Avoid hitting yourself and throw | ||||
| 	local throw_speed = 12 | ||||
| 	else -- Avoid hitting yourself and throw | ||||
| 		local throw_speed = SPEARS_THROW_SPEED | ||||
| 		while vector.distance(player_pos, throw_pos) < 1.2 do | ||||
| 			throw_pos = vector.add(throw_pos, vector.multiply(direction, 0.1)) | ||||
| 		end | ||||
| @@ -28,10 +36,11 @@ function spears_throw (itemstack, player, pointed_thing) | ||||
| 		spear_object:set_velocity(vector.add(player_vel, vector.multiply(direction, throw_speed))) | ||||
| 		spear_object:set_rotation(rotation) | ||||
| 		minetest.sound_play("spears_throw", {pos = player_pos}, true) | ||||
| 	spear_object:get_luaentity()._wear = itemstack:get_wear() | ||||
| 		spear_object:get_luaentity()._wear = wear | ||||
| 		spear_object:get_luaentity()._stickpos = nil | ||||
| 		return true | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function spears_set_entity(spear_type, base_damage, toughness) | ||||
| 	local SPEAR_ENTITY={ | ||||
| @@ -59,36 +68,27 @@ function spears_set_entity(spear_type, base_damage, toughness) | ||||
| 		end, | ||||
|  | ||||
| 		on_step = function(self, dtime) | ||||
| 			if not self._wear then | ||||
| 			local wear = self._wear | ||||
| 			if wear == nil then | ||||
| 				self.object:remove() | ||||
| 				return | ||||
| 				return false | ||||
| 			end | ||||
| 			local pos = self.object:get_pos() | ||||
| 			local velocity = self.object:get_velocity() | ||||
| 			local speed = vector.length(velocity) | ||||
| 			-- Spear is stuck ? | ||||
| 			if self._stickpos then | ||||
| 			if self._stickpos ~= nil then -- Spear is stuck | ||||
| 				local node = minetest.get_node(self._stickpos) | ||||
| 				local node_cracky = minetest.registered_nodes[node.name].groups.cracky | ||||
| 				if node_cracky and node_cracky < 3 then | ||||
| 					minetest.sound_play("default_metal_footstep", {pos = pos}, true) | ||||
| 				local check_node = spears_check_node(node.name) | ||||
| 				if check_node ~= SPEARS_NODE_STICKY then -- Fall when node is removed | ||||
| 					self.object:remove() | ||||
| 					minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = self._wear}) | ||||
| 				elseif not self._node_walkable then | ||||
| 					minetest.sound_play("default_place_node", {pos = pos}, true) | ||||
| 				end | ||||
| 				self._node_walkable = minetest.registered_nodes[node.name].walkable			 | ||||
| 				if not node or not self._node_walkable then -- Fall when node is removed | ||||
| 					self.object:remove() | ||||
| 					minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = self._wear}) | ||||
| 					return | ||||
| 					minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = wear}) | ||||
| 					return false | ||||
| 				end | ||||
| 			else -- Spear is flying | ||||
| 				local direction = vector.normalize(velocity) | ||||
| 				local yaw = minetest.dir_to_yaw(direction) | ||||
| 				local pitch = math.acos(velocity.y/speed) - math.pi/3 | ||||
| 				local spearhead_pos = vector.add(pos, vector.multiply(direction, 0.5)) | ||||
| 				local node = minetest.get_node(spearhead_pos) | ||||
| 				self.object:set_rotation({x = 0, y = yaw + math.pi/2, z = pitch}) | ||||
| 				-- Hit someone? | ||||
| 				local objects_in_radius = minetest.get_objects_inside_radius(spearhead_pos, 0.6) | ||||
| @@ -98,26 +98,39 @@ function spears_set_entity(spear_type, base_damage, toughness) | ||||
| 						object:punch(self.object, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy=damage},}, direction) | ||||
| 						self.object:remove() | ||||
| 						minetest.sound_play("spears_hit", {pos = pos}, true) | ||||
| 						minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = self._wear + 65535/toughness}) | ||||
| 						return | ||||
| 						wear = spears_wear(wear, toughness) | ||||
| 						minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = wear}) | ||||
| 						return true | ||||
| 					end | ||||
| 				end | ||||
| 				-- Hit a node? | ||||
| 				if node and minetest.registered_nodes[node.name].walkable | ||||
| 				and not minetest.registered_nodes[node.name].buildable_to | ||||
| 				and not (minetest.registered_nodes[node.name].groups.slab and spearhead_pos.y % 1 < 0.5) | ||||
| 				then -- Stick | ||||
| 					self.object:set_acceleration({x = 0, y = 0, z = 0}) | ||||
| 					self.object:set_velocity({x = 0, y = 0, z = 0}) | ||||
| 					self._wear = self._wear + 65535/toughness | ||||
| 					if self._wear >= 65535 then | ||||
| 				local node = minetest.get_node(spearhead_pos) | ||||
| 				local check_node = spears_check_node(node.name) | ||||
| 				if check_node == SPEARS_NODE_UNKNOWN then | ||||
| 					self.object:remove() | ||||
| 					minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = wear}) | ||||
| 				elseif check_node ~= SPEARS_NODE_THROUGH then | ||||
| 					wear = spears_wear(wear, toughness) | ||||
| 					if wear >= 65535 then | ||||
| 						minetest.sound_play("default_tool_breaks", {pos = pos}, true) | ||||
| 						self.object:remove() | ||||
| 						return | ||||
| 					end | ||||
| 						minetest.add_item(pos, {name='defaut:stick'}) | ||||
| 						return false | ||||
| 					elseif check_node == SPEARS_NODE_CRACKY then | ||||
| 						minetest.sound_play("default_metal_footstep", {pos = pos}, true) | ||||
| 						self.object:remove() | ||||
| 						minetest.add_item(pos, {name='spears:spear_' .. spear_type, wear = wear}) | ||||
| 						return false | ||||
| 					elseif check_node == SPEARS_NODE_STICKY then | ||||
| 						self.object:set_acceleration(SPEARS_V_ZERO) | ||||
| 						self.object:set_velocity(SPEARS_V_ZERO) | ||||
| 						minetest.sound_play("default_place_node", {pos = pos}, true) | ||||
| 						self._stickpos = spearhead_pos | ||||
| 						self._wear = wear | ||||
| 					end | ||||
| 				else -- Get drag | ||||
| 					local drag = math.max(minetest.registered_nodes[node.name].liquid_viscosity, 0.1) | ||||
| 					local viscosity = minetest.registered_nodes[node.name].liquid_viscosity | ||||
| 					local drag = math.max(viscosity, SPEARS_DRAG_COEFF) | ||||
| 					local acceleration = vector.multiply(velocity, -drag) | ||||
| 					acceleration.y = acceleration.y - 10 * ((7 - drag) / 7) | ||||
| 					self.object:set_acceleration(acceleration) | ||||
| @@ -127,3 +140,26 @@ function spears_set_entity(spear_type, base_damage, toughness) | ||||
| 	} | ||||
| 	return SPEAR_ENTITY | ||||
| end | ||||
|  | ||||
| function spears_check_node(node_name) | ||||
| 	local node = minetest.registered_nodes[node_name] | ||||
| 	if node == nil then | ||||
| 		return SPEARS_NODE_UNKNOWN | ||||
| 	elseif node.groups.cracky ~= nil and node.groups.cracky < SPEARS_NODE_CRACKY_LIMIT then | ||||
| 		return SPEARS_NODE_CRACKY | ||||
| 	elseif node.walkable and not node.buildable then | ||||
| 		return SPEARS_NODE_STICKY | ||||
| 	else | ||||
| 		return SPEARS_NODE_THROUGH | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function spears_wear(initial_wear, toughness) | ||||
| 	if not minetest.settings:get_bool("creative_mode") then | ||||
| 		local wear = initial_wear + 65535/toughness | ||||
| 		return wear | ||||
| 	else | ||||
| 		local wear = initial_wear | ||||
| 		return wear | ||||
| 	end | ||||
| end | ||||
|   | ||||
| @@ -5,3 +5,4 @@ DISABLE_BRONZE_SPEAR = true | ||||
| DISABLE_DIAMOND_SPEAR = true | ||||
| DISABLE_OBSIDIAN_SPEAR = true | ||||
| DISABLE_GOLD_SPEAR = true | ||||
| SPEARS_THROW_SPEED = 13 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user