commit 5fcb2bd3e825f7bf829386248e819aeb45a2124f Author: stub Date: Wed Sep 27 18:08:49 2017 +0300 initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c1fc9e --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ + ## Throwing mod reloaded + + #### This is a mirror of throwing mod for minetest by Echoes91, which was further improved by MinetestForFun team. + * Being an excellent ranged weapons mod for minetest already, it was further improved by MinetestForFun team, enabling PvP-damage, mob anger towards the attacker, resolved many bugs and optimized the code. It's fully suited and ready for survival and pvp gameplay. Since MinetestForFun didn't have separate repo for this mod (it only exists as a part of their server modpack), I decided to fork it (so it would be easily accesible for git clone) and make some changes to have less dependencies. + * Changes: I restored original, low-res textures by Echoes91, changed parameters of bows to shoot further and removed some items to not depend on some mods (minotaur horn bow and mithril arrows). + #### Credits + All copyright belongs to MinetestForFun team, Echoes91, PilzAdam and Jeija. + Sourcecode: LGPLv2.1 (see http://www.gnu.org/licenses/lgpl-2.1.html) + Grahpics & sounds: CC-BY 3.0 (see http://creativecommons.org/licenses/by/3.0/legalcode) + + diff --git a/build_arrow.lua b/build_arrow.lua new file mode 100755 index 0000000..6c66828 --- /dev/null +++ b/build_arrow.lua @@ -0,0 +1,117 @@ +minetest.register_craftitem("throwing:arrow_build", { + description = "Build Arrow", + inventory_image = "throwing_arrow_build.png", +}) + +minetest.register_node("throwing:arrow_build_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + timer=0, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_build_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + node = "", + player = "", + inventory = false, + stack = false, + bow_damage = 0, +} + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + self.timer=self.timer+dtime + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if self.inventory and self.stack and not minetest.setting_getbool("creative_mode") then + self.inventory:remove_item("main", {name=self.stack:get_name()}) + end + if self.stack then + minetest.add_item(pos, {name=self.stack:get_name()}) + end + local toughness = 0.95 + if math.random() < toughness then + minetest.add_item(pos, 'throwing:arrow_build') + else + minetest.add_item(pos, 'default:stick') + end + self.object:remove() + return + end + end + + if node.name ~= "air" + and not string.find(node.name, "water_") + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + if node.name ~= "ignore" and self.inventory and self.stack then + if not minetest.is_protected(self.lastpos, "") + and not string.find(node.name, "lava") + and not string.find(node.name, "torch") + and self.stack:get_definition().type == "node" + and self.stack:get_name() ~= "default:torch" then + minetest.place_node(self.lastpos, {name=self.stack:get_name()}) + else + minetest.add_item(self.lastpos, {name=self.stack:get_name()}) + end + if not minetest.setting_getbool("creative_mode") then + self.inventory:remove_item("main", {name=self.stack:get_name()}) + end + end + minetest.add_item(self.lastpos, 'default:shovel_steel') + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + +minetest.register_entity("throwing:arrow_build_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_build', + recipe = { + {'default:stick', 'default:stick', 'default:shovel_steel'}, + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_build', + recipe = { + {'default:shovel_steel', 'default:stick', 'default:stick'}, + } +}) diff --git a/defaults.lua b/defaults.lua new file mode 100755 index 0000000..90518fa --- /dev/null +++ b/defaults.lua @@ -0,0 +1,25 @@ +DISABLE_WOODEN_BOW = false +DISABLE_LONGBOW = false +DISABLE_COMPOSITE_BOW = false +DISABLE_STEEL_BOW = false +DISABLE_ROYAL_BOW = false +DISABLE_CROSSBOW = false +DISABLE_ARBALEST = false +DISABLE_AUTOMATED_ARBALEST = false + +DISABLE_TELEPORT_ARROW = true +DISABLE_DIG_ARROW = true +DISABLE_BUILD_ARROW = true +DISABLE_TNT_ARROW = true +DISABLE_FIRE_ARROW = true +DISABLE_TORCH_ARROW = false +DISABLE_SHELL_ARROW = false + +DISABLE_FIREWORKS_BLUE_ARROW = false +DISABLE_FIREWORKS_RED_ARROW = false + +DISABLE_STONE_ARROW = false +DISABLE_STEEL_ARROW = false +DISABLE_DIAMOND_ARROW = false +DISABLE_OBSIDIAN_ARROW = false + diff --git a/depends.txt b/depends.txt new file mode 100755 index 0000000..db178d1 --- /dev/null +++ b/depends.txt @@ -0,0 +1,6 @@ +default +farming +dye +bucket? +fire? +tnt? diff --git a/description.txt b/description.txt new file mode 100755 index 0000000..ee25fb4 --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +This mod adds many bows and arrows to Minetest. diff --git a/dig_arrow.lua b/dig_arrow.lua new file mode 100755 index 0000000..0a676b5 --- /dev/null +++ b/dig_arrow.lua @@ -0,0 +1,109 @@ +minetest.register_craftitem("throwing:arrow_dig", { + description = "Dig Arrow", + inventory_image = "throwing_arrow_dig.png", +}) + +minetest.register_node("throwing:arrow_dig_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + timer=0, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_dig_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, +} + + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if throwing_touch(pos, obj:getpos()) then + local puncher = self.object + if self.player and minetest.get_player_by_name(self.player) then + puncher = minetest.get_player_by_name(self.player) + end + local damage = 1.5 + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(puncher, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + if math.random(0,100) % 2 == 0 then -- 50% of chance to drop //MFF (Mg|07/27/15) + minetest.add_item(pos, "throwing:arrow_dig") + end + self.object:remove() + return + end + end + end + if node.name ~= "air" + and not string.find(node.name, "water_") + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + if node.name ~= "ignore" and minetest.get_item_group(node.name, "unbreakable") == 0 + and not minetest.is_protected(pos, self.player) + and node.diggable ~= false then + minetest.set_node(pos, {name = "air"}) + minetest.add_item(pos, node.name) + end + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + +minetest.register_entity("throwing:arrow_dig_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_dig', + recipe = { + {'default:stick', 'default:stick', 'default:pick_steel'}, + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_dig', + recipe = { + {'default:pick_steel', 'default:stick', 'default:stick'}, + } +}) diff --git a/fire_arrow.lua b/fire_arrow.lua new file mode 100755 index 0000000..424d81c --- /dev/null +++ b/fire_arrow.lua @@ -0,0 +1,145 @@ +minetest.register_craftitem("throwing:arrow_fire", { + description = "Fire Arrow", + inventory_image = "throwing_arrow_fire.png", +}) + +minetest.register_node("throwing:arrow_fire_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_fire.png", "throwing_arrow_fire.png", "throwing_arrow_fire_back.png", "throwing_arrow_fire_front.png", "throwing_arrow_fire_2.png", "throwing_arrow_fire.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_fire_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, +} + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + local objpos = obj:getpos() + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if throwing_touch(pos, objpos) then + local puncher = self.object + if self.player and minetest.get_player_by_name(self.player) then + puncher = minetest.get_player_by_name(self.player) + end + local damage = 4 + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(puncher, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + if math.random(0,100) % 2 == 0 then -- 50% of chance to drop //MFF (Mg|07/27/15) + minetest.add_item(pos, 'default:stick') + end + self.object:remove() + return + end + end + end + + if node.name ~= "air" + and node.name ~= "throwing:light" + and node.name ~= "fire:basic_flame" + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + if node.name ~= "ignore" then + minetest.set_node(self.lastpos, {name="fire:basic_flame"}) + end + self.object:remove() + return + end + + if minetest.get_node(pos).name == "air" then + minetest.set_node(pos, {name="throwing:light"}) + end + if minetest.get_node(self.lastpos).name == "throwing:light" then + minetest.remove_node(self.lastpos) + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + + +minetest.register_entity("throwing:arrow_fire_entity", THROWING_ARROW_ENTITY) + +minetest.register_node("throwing:light", { + drawtype = "airlike", + paramtype = "light", + sunlight_propagates = true, + tiles = {"throwing_empty.png"}, + light_source = default.LIGHT_MAX-4, + selection_box = { + type = "fixed", + fixed = { + {0,0,0,0,0,0} + } + }, + groups = {not_in_creative_inventory=1} +}) + +minetest.register_abm({ + nodenames = {"throwing:light"}, + interval = 10, + chance = 1, + action = function(pos, node) + minetest.remove_node(pos) + end +}) + +minetest.register_craft({ + output = 'throwing:arrow_fire 4', + recipe = { + {'default:stick', 'default:stick', 'bucket:bucket_lava'}, + }, + replacements = { + {"bucket:bucket_lava", "bucket:bucket_empty"} + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_fire 4', + recipe = { + {'bucket:bucket_lava', 'default:stick', 'default:stick'}, + }, + replacements = { + {"bucket:bucket_lava", "bucket:bucket_empty"} + } +}) diff --git a/fireworks_arrows.lua b/fireworks_arrows.lua new file mode 100755 index 0000000..167f8b8 --- /dev/null +++ b/fireworks_arrows.lua @@ -0,0 +1,197 @@ +local function throwing_register_fireworks(color, desc) + minetest.register_craftitem("throwing:arrow_fireworks_" .. color, { + description = desc .. "fireworks arrow", + inventory_image = "throwing_arrow_fireworks_" .. color .. ".png", + }) + + minetest.register_node("throwing:arrow_fireworks_" .. color .. "_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_fireworks_" .. color .. ".png", "throwing_arrow_fireworks_" .. color .. ".png", "throwing_arrow_fireworks_" .. color .. "_back.png", "throwing_arrow_fireworks_" .. color .. "_front.png", "throwing_arrow_fireworks_" .. color .. "_2.png", "throwing_arrow_fireworks_" .. color .. ".png"}, + groups = {not_in_creative_inventory=1}, + }) + + local THROWING_ARROW_ENTITY={ + physical = false, + timer=0, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_fireworks_" .. color .. "_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, + } + + local radius = 0.5 + + local function add_effects(pos, radius) + minetest.add_particlespawner({ + amount = 256, + time = 0.2, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-5, y=-5, z=-5}, + maxvel = {x=5, y=5, z=5}, + minacc = {x=0, y=-8, z=0}, + --~ maxacc = {x=-20, y=-50, z=-50}, + minexptime = 2.5, + maxexptime = 3, + minsize = 1, + maxsize = 2.5, + texture = "throwing_sparkle_" .. color .. ".png", + }) + end + + + local function boom(pos) + minetest.sound_play("throwing_firework_boom", {pos=pos, gain=1, max_hear_distance=2*64}) + if minetest.get_node(pos).name == 'air' or minetest.get_node(pos).name == 'throwing:firework_trail' then + minetest.add_node(pos, {name="throwing:firework_boom"}) + minetest.get_node_timer(pos):start(0.2) + end + add_effects(pos, radius) + end + + -- Back to the arrow + + THROWING_ARROW_ENTITY.on_step = function(self, dtime) + self.timer=self.timer+dtime + local newpos = self.object:getpos() + if self.timer < 0.07 then + minetest.sound_play("throwing_firework_launch", {pos=newpos, gain=0.8, max_hear_distance=2*64}) + end + minetest.add_particlespawner({ + amount = 16, + time = 0.1, + minpos = newpos, + maxpos = newpos, + minvel = {x=-5, y=-5, z=-5}, + maxvel = {x=5, y=5, z=5}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 0.3, + maxexptime = 0.5, + minsize = 0.5, + maxsize = 1, + texture = "throwing_sparkle.png", + }) + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + local damage = 2 + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + boom(pos) + self.object:remove() + return + end + end + end + local node = minetest.get_node(newpos) + if self.timer > 2 or node.name ~= "air" and node.name ~= "throwing:firework_trail" then + boom(self.lastpos) + self.object:remove() + return + end + if node.name == 'air' then + minetest.add_node(newpos, {name="throwing:firework_trail"}) + minetest.get_node_timer(newpos):start(0.1) + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} + end + + + minetest.register_entity("throwing:arrow_fireworks_" .. color .. "_entity", THROWING_ARROW_ENTITY) + + minetest.register_craft({ + output = 'throwing:arrow_fireworks_' .. color .. ' 8', + recipe = { + {'default:stick', 'tnt:gunpowder', 'dye:' .. color}, + } + }) + + minetest.register_craft({ + output = 'throwing:arrow_fireworks_' .. color .. ' 8', + recipe = { + {'dye:' .. color, 'tnt:gunpowder', 'default:stick'}, + } + }) +end + +--~ Arrows + +if not DISABLE_FIREWORKS_BLUE_ARROW then + throwing_register_fireworks('blue', 'Blue') +end + +if not DISABLE_FIREWORKS_RED_ARROW then + throwing_register_fireworks('red', 'Red') +end + +--~ Nodes + +minetest.register_node("throwing:firework_trail", { + drawtype = "airlike", + light_source = 9, + walkable = false, + drop = "", + groups = {dig_immediate=3}, + on_timer = function(pos, elapsed) + minetest.remove_node(pos) + end, +}) + +minetest.register_node("throwing:firework_boom", { + drawtype = "plantlike", + tiles = {"throwing_sparkle.png"}, + light_source = default.LIGHT_MAX, + walkable = false, + drop = "", + groups = {dig_immediate=3}, + on_timer = function(pos, elapsed) + minetest.remove_node(pos) + end, + after_destruct = function(pos, oldnode) + minetest.set_node(pos, {name="throwing:firework_light"}) + minetest.get_node_timer(pos):start(3) + end, +}) + +minetest.register_node("throwing:firework_light", { + drawtype = "airlike", + light_source = default.LIGHT_MAX, + walkable = false, + drop = "", + groups = {dig_immediate=3}, + on_timer = function(pos, elapsed) + minetest.remove_node(pos) + end, +}) diff --git a/functions.lua b/functions.lua new file mode 100755 index 0000000..0deb46f --- /dev/null +++ b/functions.lua @@ -0,0 +1,191 @@ +--~ +--~ Shot and reload system +--~ + +local players = {} + +minetest.register_on_joinplayer(function(player) + local playerName = player:get_player_name() + players[playerName] = { + reloading=false, + } +end) + +minetest.register_on_leaveplayer(function(player) + local playerName = player:get_player_name() + players[playerName] = nil +end) + +function throwing_is_player(name, obj) + return (obj:is_player() and obj:get_player_name() ~= name) +end + +function throwing_is_entity(obj) + return (obj:get_luaentity() ~= nil + and not string.find(obj:get_luaentity().name, "throwing:") + and obj:get_luaentity().name ~= "__builtin:item" + and obj:get_luaentity().name ~= "gauges:hp_bar" + and obj:get_luaentity().name ~= "signs:text") +end + +function throwing_get_trajectoire(self, newpos) + if self.lastpos.x == nil then + return {newpos} + end + local coord = {} + local nx = (newpos["x"] - self.lastpos["x"])/3 + local ny = (newpos["y"] - self.lastpos["y"])/3 + local nz = (newpos["z"] - self.lastpos["z"])/3 + + if nx and ny and nz then + table.insert(coord, {x=self.lastpos["x"]+nx, y=self.lastpos["y"]+ny ,z=self.lastpos["z"]+nz }) + table.insert(coord, {x=newpos["x"]-nx, y=newpos["y"]-ny ,z=newpos["z"]-nz }) + end + table.insert(coord, newpos) + return coord +end + +function throwing_touch(pos, objpos) + local rx = pos.x - objpos.x + local ry = pos.y - (objpos.y+1) + local rz = pos.z - objpos.z + if (ry < 1 and ry > -1) and (rx < 1 and rx > -1) and (rz < 1 and rz > -1) then + return true + end + return false +end + +function throwing_shoot_arrow (itemstack, player, stiffness, is_cross) + if not player then return end + local arrow = itemstack:get_metadata() + itemstack:set_metadata("") + player:set_wielded_item(itemstack) + local playerpos = player:getpos() + local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow) + if not obj then return end + local dir = player:get_look_dir() + obj:setvelocity({x=dir.x*stiffness, y=dir.y*stiffness, z=dir.z*stiffness}) + obj:setacceleration({x=dir.x*-3, y=-10, z=dir.z*-3}) + obj:setyaw(player:get_look_yaw()+math.pi) + if is_cross then + minetest.sound_play("throwing_crossbow_sound", {pos=playerpos}) + else + minetest.sound_play("throwing_bow_sound", {pos=playerpos}) + end + if obj:get_luaentity() then + obj:get_luaentity().player = player:get_player_name() + obj:get_luaentity().inventory = player:get_inventory() + obj:get_luaentity().stack = player:get_inventory():get_stack("main", player:get_wield_index()-1) + obj:get_luaentity().lastpos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z} + obj:get_luaentity().bow_damage = stiffness + end + return true +end + +function throwing_unload (itemstack, player, unloaded, wear) + if itemstack:get_metadata() then + for _,arrow in ipairs(throwing_arrows) do + if itemstack:get_metadata() == arrow[2] then + if not minetest.setting_getbool("creative_mode") then + player:get_inventory():add_item("main", arrow[1]) + end + break + end + end + end + if wear >= 65535 then + player:set_wielded_item({}) + else + player:set_wielded_item({name=unloaded, wear=wear}) + end +end + +function throwing_reload (itemstack, player, pos, is_cross, loaded) + local playerName = player:get_player_name() + players[playerName]['reloading'] = false + if itemstack:get_name() == player:get_wielded_item():get_name() then + if (pos.x == player:getpos().x and pos.y == player:getpos().y and pos.z == player:getpos().z) or not is_cross then + local wear = itemstack:get_wear() + for _,arrow in ipairs(throwing_arrows) do + if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then + if not minetest.setting_getbool("creative_mode") then + player:get_inventory():remove_item("main", arrow[1]) + end + local meta = arrow[2] + player:set_wielded_item({name=loaded, wear=wear, metadata=meta}) + break + end + end + end + end +end + +-- Bows and crossbows + +function throwing_register_bow (name, desc, scale, stiffness, reload_time, toughness, is_cross, craft) + minetest.register_tool("throwing:" .. name, { + description = desc, + inventory_image = "throwing_" .. name .. ".png", + wield_scale = scale, + stack_max = 1, + on_use = function(itemstack, user, pointed_thing) + local pos = user:getpos() + local playerName = user:get_player_name() + if not players[playerName]['reloading'] then + players[playerName]['reloading'] = true + minetest.after(reload_time, throwing_reload, itemstack, user, pos, is_cross, "throwing:" .. name .. "_loaded") + end + return itemstack + end, + }) + + minetest.register_tool("throwing:" .. name .. "_loaded", { + description = desc, + inventory_image = "throwing_" .. name .. "_loaded.png", + wield_scale = scale, + stack_max = 1, + on_use = function(itemstack, user, pointed_thing) + local wear = itemstack:get_wear() + if not minetest.setting_getbool("creative_mode") then + wear = wear + (65535/toughness) + end + local unloaded = "throwing:" .. name + throwing_shoot_arrow(itemstack, user, stiffness, is_cross) + minetest.after(0, throwing_unload, itemstack, user, unloaded, wear) + return itemstack + end, + on_drop = function(itemstack, dropper, pointed_thing) + local wear = itemstack:get_wear() + local unloaded = "throwing:" .. name + minetest.after(0, throwing_unload, itemstack, dropper, unloaded, wear) + end, + groups = {not_in_creative_inventory=1}, + }) + + minetest.register_craft({ + output = 'throwing:' .. name, + recipe = craft + }) + + local craft_width = 1 + -- Since # isn't stable especially when there are nils in the table, count by hand + for _,v in ipairs(craft) do + for i,__ in ipairs(v) do + if i > craft_width then + craft_width = i + end + end + end + local rev_craft = {} + for i,y in ipairs(craft) do + rev_craft[i] = {} + for j,x in ipairs(y) do + rev_craft[i][craft_width-j+1] = x + end + end + minetest.register_craft({ + output = 'throwing:' .. name, + recipe = rev_craft + }) +end + diff --git a/init.lua b/init.lua new file mode 100755 index 0000000..162af8e --- /dev/null +++ b/init.lua @@ -0,0 +1,67 @@ +throwing_arrows = { + {"throwing:arrow_steel", "throwing:arrow_steel_entity"}, + {"throwing:arrow_stone", "throwing:arrow_stone_entity"}, + {"throwing:arrow_obsidian", "throwing:arrow_obsidian_entity"}, + {"throwing:arrow_diamond", "throwing:arrow_diamond_entity"}, + {"throwing:arrow_fire", "throwing:arrow_fire_entity"}, + {"throwing:arrow_teleport", "throwing:arrow_teleport_entity"}, + {"throwing:arrow_dig", "throwing:arrow_dig_entity"}, + {"throwing:arrow_build", "throwing:arrow_build_entity"}, + {"throwing:arrow_tnt", "throwing:arrow_tnt_entity"}, + {"throwing:arrow_torch", "throwing:arrow_torch_entity"}, + {"throwing:arrow_shell", "throwing:arrow_shell_entity"}, + {"throwing:arrow_fireworks_blue", "throwing:arrow_fireworks_blue_entity"}, + {"throwing:arrow_fireworks_red", "throwing:arrow_fireworks_red_entity"}, +} + +dofile(minetest.get_modpath("throwing").."/defaults.lua") + +local input = io.open(minetest.get_modpath("throwing").."/throwing.conf", "r") +if input then + dofile(minetest.get_modpath("throwing").."/throwing.conf") + input:close() + input = nil +end + +dofile(minetest.get_modpath("throwing").."/functions.lua") + +dofile(minetest.get_modpath("throwing").."/tools.lua") + +dofile(minetest.get_modpath("throwing").."/standard_arrows.lua") + + +if minetest.get_modpath('fire') and minetest.get_modpath('bucket') and not DISABLE_FIRE_ARROW then + dofile(minetest.get_modpath("throwing").."/fire_arrow.lua") +end + +if not DISABLE_TELEPORT_ARROW then + dofile(minetest.get_modpath("throwing").."/teleport_arrow.lua") +end + +if not DISABLE_DIG_ARROW then + dofile(minetest.get_modpath("throwing").."/dig_arrow.lua") +end + +if not DISABLE_BUILD_ARROW then + dofile(minetest.get_modpath("throwing").."/build_arrow.lua") +end + +if minetest.get_modpath('fire') and minetest.get_modpath('tnt') and not DISABLE_TNT_ARROW then + dofile(minetest.get_modpath("throwing").."/tnt_arrow.lua") +end + +if not DISABLE_TORCH_ARROW then + dofile(minetest.get_modpath("throwing").."/torch_arrow.lua") +end + +if minetest.get_modpath('tnt') and not DISABLE_SHELL_ARROW then + dofile(minetest.get_modpath("throwing").."/shell_arrow.lua") +end + +if minetest.get_modpath('tnt') then + dofile(minetest.get_modpath("throwing").."/fireworks_arrows.lua") +end + +if minetest.setting_get("log_mods") then + minetest.log("action", "throwing loaded") +end diff --git a/shell_arrow.lua b/shell_arrow.lua new file mode 100755 index 0000000..f652a6b --- /dev/null +++ b/shell_arrow.lua @@ -0,0 +1,126 @@ +minetest.register_craftitem("throwing:arrow_shell", { + description = "Shell arrow", + inventory_image = "throwing_arrow_shell.png", +}) + +minetest.register_node("throwing:arrow_shell_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_shell.png", "throwing_arrow_shell.png", "throwing_arrow_shell_back.png", "throwing_arrow_shell_front.png", "throwing_arrow_shell_2.png", "throwing_arrow_shell.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + timer=0, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_shell_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, +} + +local radius = 1 + +local function add_effects(pos, radius) + minetest.add_particlespawner({ + amount = 8, + time = 0.5, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-10, y=-10, z=-10}, + maxvel = {x=10, y=10, z=10}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 0.5, + maxexptime = 1, + minsize = 0.5, + maxsize = 1, + texture = "tnt_smoke.png", + }) +end + + +local function boom(pos) + minetest.sound_play("shell_explode", {pos=pos, gain=1.5, max_hear_distance=2*64}) + minetest.set_node(pos, {name="tnt:boom"}) + minetest.get_node_timer(pos):start(0.1) + add_effects(pos, radius) +end + +-- Back to the arrow + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + local speed = vector.length(self.object:getvelocity()) + local damage = ((speed + 5)^1.2)/10 + 12 + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(self.object, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + boom(pos) + self.object:remove() + return + end + end + + if node.name ~= "air" + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + boom(self.lastpos) + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + +minetest.register_entity("throwing:arrow_shell_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_shell 8', + recipe = { + {'default:stick', 'tnt:gunpowder', 'default:bronze_ingot'}, + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_shell 8', + recipe = { + {'default:bronze_ingot', 'tnt:gunpowder', 'default:stick'}, + } +}) diff --git a/sounds/throwing_bow_sound.ogg b/sounds/throwing_bow_sound.ogg new file mode 100755 index 0000000..20a51da Binary files /dev/null and b/sounds/throwing_bow_sound.ogg differ diff --git a/sounds/throwing_crossbow_sound.ogg b/sounds/throwing_crossbow_sound.ogg new file mode 100755 index 0000000..bccb7f5 Binary files /dev/null and b/sounds/throwing_crossbow_sound.ogg differ diff --git a/sounds/throwing_firework_boom.ogg b/sounds/throwing_firework_boom.ogg new file mode 100755 index 0000000..5db9100 Binary files /dev/null and b/sounds/throwing_firework_boom.ogg differ diff --git a/sounds/throwing_firework_launch.ogg b/sounds/throwing_firework_launch.ogg new file mode 100755 index 0000000..d15c573 Binary files /dev/null and b/sounds/throwing_firework_launch.ogg differ diff --git a/sounds/throwing_shell_explode.ogg b/sounds/throwing_shell_explode.ogg new file mode 100755 index 0000000..38b8e93 Binary files /dev/null and b/sounds/throwing_shell_explode.ogg differ diff --git a/standard_arrows.lua b/standard_arrows.lua new file mode 100755 index 0000000..8ac6a99 --- /dev/null +++ b/standard_arrows.lua @@ -0,0 +1,131 @@ +function throwing_register_arrow_standard (kind, desc, eq, toughness, craft) + minetest.register_craftitem("throwing:arrow_" .. kind, { + description = desc .. " arrow", + inventory_image = "throwing_arrow_" .. kind .. ".png", + }) + + minetest.register_node("throwing:arrow_" .. kind .. "_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_" .. kind .. ".png", "throwing_arrow_" .. kind .. ".png", "throwing_arrow_" .. kind .. "_back.png", "throwing_arrow_" .. kind .. "_front.png", + "throwing_arrow_" .. kind .. "_2.png", "throwing_arrow_" .. kind .. ".png"}, + groups = {not_in_creative_inventory=1}, + }) + + local THROWING_ARROW_ENTITY={ + physical = false, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_" .. kind .. "_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, + } + + THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + local objpos = obj:getpos() + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if throwing_touch(pos, objpos) then + local puncher = self.object + if self.player and minetest.get_player_by_name(self.player) then + puncher = minetest.get_player_by_name(self.player) + end + local damage = eq + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(puncher, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + if math.random() < toughness then + if math.random(0,100) % 2 == 0 then + minetest.add_item(self.lastpos, 'throwing:arrow_' .. kind) + end + else + minetest.add_item(self.lastpos, 'default:stick') + end + self.object:remove() + return + end + end + end + if node.name ~= "air" + and not string.find(node.name, 'water_') + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + if math.random() < toughness then + minetest.add_item(self.lastpos, 'throwing:arrow_' .. kind) + else + minetest.add_item(self.lastpos, 'default:stick') + end + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} + end + + minetest.register_entity("throwing:arrow_" .. kind .. "_entity", THROWING_ARROW_ENTITY) + + minetest.register_craft({ + output = 'throwing:arrow_' .. kind .. ' 16', + recipe = { + {'default:stick', 'default:stick', craft}, + } + }) + + minetest.register_craft({ + output = 'throwing:arrow_' .. kind .. ' 16', + recipe = { + {craft, 'default:stick', 'default:stick'}, + } + }) +end + +if not DISABLE_STONE_ARROW then + throwing_register_arrow_standard ('stone', 'Stone', 4, 0.40, 'group:stone') +end + +if not DISABLE_STEEL_ARROW then + throwing_register_arrow_standard ('steel', 'Steel', 5, 0.50, 'default:steel_ingot') +end + +if not DISABLE_OBSIDIAN_ARROW then + throwing_register_arrow_standard ('obsidian', 'Obsidian', 6, 0.60, 'default:obsidian') +end + +if not DISABLE_DIAMOND_ARROW then + throwing_register_arrow_standard ('diamond', 'Diamond', 7, 0.70, 'default:diamond') +end + diff --git a/teleport_arrow.lua b/teleport_arrow.lua new file mode 100755 index 0000000..927681f --- /dev/null +++ b/teleport_arrow.lua @@ -0,0 +1,96 @@ +minetest.register_craftitem("throwing:arrow_teleport", { + description = "Teleport Arrow", + inventory_image = "throwing_arrow_teleport.png", +}) + +minetest.register_node("throwing:arrow_teleport_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_teleport_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + player = "", + bow_damage = 0, +} + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if self.player ~= "" then + local player = minetest.get_player_by_name(self.player) + if player then + player:setpos(self.lastpos) + end + end + self.object:remove() + return + end + end + + if node.name ~= "air" + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + if self.player ~= "" then + local player = minetest.get_player_by_name(self.player) + if player then + player:setpos(self.lastpos) + end + end + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + +minetest.register_entity("throwing:arrow_teleport_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_teleport', + recipe = { + {'default:stick', 'default:stick', 'default:mese_crystal_fragment'} + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_teleport', + recipe = { + {'default:mese_crystal_fragment', 'default:stick', 'default:stick'} + } +}) diff --git a/textures/.directory b/textures/.directory new file mode 100644 index 0000000..5c39294 --- /dev/null +++ b/textures/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2017,9,27,1,19,11 +Version=4 diff --git a/textures/throwing_arbalest.png b/textures/throwing_arbalest.png new file mode 100644 index 0000000..f53e377 Binary files /dev/null and b/textures/throwing_arbalest.png differ diff --git a/textures/throwing_arbalest_auto.png b/textures/throwing_arbalest_auto.png new file mode 100644 index 0000000..c40cd92 Binary files /dev/null and b/textures/throwing_arbalest_auto.png differ diff --git a/textures/throwing_arbalest_auto_loaded.png b/textures/throwing_arbalest_auto_loaded.png new file mode 100644 index 0000000..f971b24 Binary files /dev/null and b/textures/throwing_arbalest_auto_loaded.png differ diff --git a/textures/throwing_arbalest_loaded.png b/textures/throwing_arbalest_loaded.png new file mode 100644 index 0000000..09b2cc8 Binary files /dev/null and b/textures/throwing_arbalest_loaded.png differ diff --git a/textures/throwing_arrow_build.png b/textures/throwing_arrow_build.png new file mode 100644 index 0000000..d9b4062 Binary files /dev/null and b/textures/throwing_arrow_build.png differ diff --git a/textures/throwing_arrow_build_2.png b/textures/throwing_arrow_build_2.png new file mode 100644 index 0000000..1e178e4 Binary files /dev/null and b/textures/throwing_arrow_build_2.png differ diff --git a/textures/throwing_arrow_build_back.png b/textures/throwing_arrow_build_back.png new file mode 100644 index 0000000..621f258 Binary files /dev/null and b/textures/throwing_arrow_build_back.png differ diff --git a/textures/throwing_arrow_build_front.png b/textures/throwing_arrow_build_front.png new file mode 100644 index 0000000..25d47ce Binary files /dev/null and b/textures/throwing_arrow_build_front.png differ diff --git a/textures/throwing_arrow_diamond.png b/textures/throwing_arrow_diamond.png new file mode 100644 index 0000000..a70038a Binary files /dev/null and b/textures/throwing_arrow_diamond.png differ diff --git a/textures/throwing_arrow_diamond_2.png b/textures/throwing_arrow_diamond_2.png new file mode 100644 index 0000000..485b12f Binary files /dev/null and b/textures/throwing_arrow_diamond_2.png differ diff --git a/textures/throwing_arrow_diamond_back.png b/textures/throwing_arrow_diamond_back.png new file mode 100644 index 0000000..0c92fba Binary files /dev/null and b/textures/throwing_arrow_diamond_back.png differ diff --git a/textures/throwing_arrow_diamond_front.png b/textures/throwing_arrow_diamond_front.png new file mode 100644 index 0000000..6e545df Binary files /dev/null and b/textures/throwing_arrow_diamond_front.png differ diff --git a/textures/throwing_arrow_dig.png b/textures/throwing_arrow_dig.png new file mode 100644 index 0000000..6a1d443 Binary files /dev/null and b/textures/throwing_arrow_dig.png differ diff --git a/textures/throwing_arrow_dig_2.png b/textures/throwing_arrow_dig_2.png new file mode 100644 index 0000000..b6d9d1b Binary files /dev/null and b/textures/throwing_arrow_dig_2.png differ diff --git a/textures/throwing_arrow_dig_back.png b/textures/throwing_arrow_dig_back.png new file mode 100644 index 0000000..3bc4a60 Binary files /dev/null and b/textures/throwing_arrow_dig_back.png differ diff --git a/textures/throwing_arrow_dig_front.png b/textures/throwing_arrow_dig_front.png new file mode 100644 index 0000000..aa7ff2e Binary files /dev/null and b/textures/throwing_arrow_dig_front.png differ diff --git a/textures/throwing_arrow_fire.png b/textures/throwing_arrow_fire.png new file mode 100644 index 0000000..fd3a9d5 Binary files /dev/null and b/textures/throwing_arrow_fire.png differ diff --git a/textures/throwing_arrow_fire_2.png b/textures/throwing_arrow_fire_2.png new file mode 100644 index 0000000..f86579a Binary files /dev/null and b/textures/throwing_arrow_fire_2.png differ diff --git a/textures/throwing_arrow_fire_back.png b/textures/throwing_arrow_fire_back.png new file mode 100644 index 0000000..8a7d993 Binary files /dev/null and b/textures/throwing_arrow_fire_back.png differ diff --git a/textures/throwing_arrow_fire_front.png b/textures/throwing_arrow_fire_front.png new file mode 100644 index 0000000..3994257 Binary files /dev/null and b/textures/throwing_arrow_fire_front.png differ diff --git a/textures/throwing_arrow_fireworks_blue.png b/textures/throwing_arrow_fireworks_blue.png new file mode 100644 index 0000000..71d4ec8 Binary files /dev/null and b/textures/throwing_arrow_fireworks_blue.png differ diff --git a/textures/throwing_arrow_fireworks_blue_2.png b/textures/throwing_arrow_fireworks_blue_2.png new file mode 100644 index 0000000..51b055c Binary files /dev/null and b/textures/throwing_arrow_fireworks_blue_2.png differ diff --git a/textures/throwing_arrow_fireworks_blue_back.png b/textures/throwing_arrow_fireworks_blue_back.png new file mode 100644 index 0000000..85956a6 Binary files /dev/null and b/textures/throwing_arrow_fireworks_blue_back.png differ diff --git a/textures/throwing_arrow_fireworks_blue_front.png b/textures/throwing_arrow_fireworks_blue_front.png new file mode 100644 index 0000000..8674cc8 Binary files /dev/null and b/textures/throwing_arrow_fireworks_blue_front.png differ diff --git a/textures/throwing_arrow_fireworks_red.png b/textures/throwing_arrow_fireworks_red.png new file mode 100644 index 0000000..9b13fcd Binary files /dev/null and b/textures/throwing_arrow_fireworks_red.png differ diff --git a/textures/throwing_arrow_fireworks_red_2.png b/textures/throwing_arrow_fireworks_red_2.png new file mode 100644 index 0000000..edb0097 Binary files /dev/null and b/textures/throwing_arrow_fireworks_red_2.png differ diff --git a/textures/throwing_arrow_fireworks_red_back.png b/textures/throwing_arrow_fireworks_red_back.png new file mode 100644 index 0000000..8e90fc5 Binary files /dev/null and b/textures/throwing_arrow_fireworks_red_back.png differ diff --git a/textures/throwing_arrow_fireworks_red_front.png b/textures/throwing_arrow_fireworks_red_front.png new file mode 100644 index 0000000..8d6a629 Binary files /dev/null and b/textures/throwing_arrow_fireworks_red_front.png differ diff --git a/textures/throwing_arrow_obsidian.png b/textures/throwing_arrow_obsidian.png new file mode 100644 index 0000000..2df7a08 Binary files /dev/null and b/textures/throwing_arrow_obsidian.png differ diff --git a/textures/throwing_arrow_obsidian_2.png b/textures/throwing_arrow_obsidian_2.png new file mode 100644 index 0000000..abccbb3 Binary files /dev/null and b/textures/throwing_arrow_obsidian_2.png differ diff --git a/textures/throwing_arrow_obsidian_back.png b/textures/throwing_arrow_obsidian_back.png new file mode 100644 index 0000000..bd1232f Binary files /dev/null and b/textures/throwing_arrow_obsidian_back.png differ diff --git a/textures/throwing_arrow_obsidian_front.png b/textures/throwing_arrow_obsidian_front.png new file mode 100644 index 0000000..2cbed4c Binary files /dev/null and b/textures/throwing_arrow_obsidian_front.png differ diff --git a/textures/throwing_arrow_shell.png b/textures/throwing_arrow_shell.png new file mode 100644 index 0000000..d100424 Binary files /dev/null and b/textures/throwing_arrow_shell.png differ diff --git a/textures/throwing_arrow_shell_2.png b/textures/throwing_arrow_shell_2.png new file mode 100644 index 0000000..25f2b3e Binary files /dev/null and b/textures/throwing_arrow_shell_2.png differ diff --git a/textures/throwing_arrow_shell_back.png b/textures/throwing_arrow_shell_back.png new file mode 100644 index 0000000..4b64eaf Binary files /dev/null and b/textures/throwing_arrow_shell_back.png differ diff --git a/textures/throwing_arrow_shell_front.png b/textures/throwing_arrow_shell_front.png new file mode 100644 index 0000000..f6d51c4 Binary files /dev/null and b/textures/throwing_arrow_shell_front.png differ diff --git a/textures/throwing_arrow_steel.png b/textures/throwing_arrow_steel.png new file mode 100644 index 0000000..9932590 Binary files /dev/null and b/textures/throwing_arrow_steel.png differ diff --git a/textures/throwing_arrow_steel_2.png b/textures/throwing_arrow_steel_2.png new file mode 100644 index 0000000..c0401a6 Binary files /dev/null and b/textures/throwing_arrow_steel_2.png differ diff --git a/textures/throwing_arrow_steel_back.png b/textures/throwing_arrow_steel_back.png new file mode 100644 index 0000000..c7edf56 Binary files /dev/null and b/textures/throwing_arrow_steel_back.png differ diff --git a/textures/throwing_arrow_steel_front.png b/textures/throwing_arrow_steel_front.png new file mode 100644 index 0000000..ff22af0 Binary files /dev/null and b/textures/throwing_arrow_steel_front.png differ diff --git a/textures/throwing_arrow_stone.png b/textures/throwing_arrow_stone.png new file mode 100644 index 0000000..b563af6 Binary files /dev/null and b/textures/throwing_arrow_stone.png differ diff --git a/textures/throwing_arrow_stone_2.png b/textures/throwing_arrow_stone_2.png new file mode 100644 index 0000000..20182bc Binary files /dev/null and b/textures/throwing_arrow_stone_2.png differ diff --git a/textures/throwing_arrow_stone_back.png b/textures/throwing_arrow_stone_back.png new file mode 100644 index 0000000..293334e Binary files /dev/null and b/textures/throwing_arrow_stone_back.png differ diff --git a/textures/throwing_arrow_stone_front.png b/textures/throwing_arrow_stone_front.png new file mode 100644 index 0000000..8b35047 Binary files /dev/null and b/textures/throwing_arrow_stone_front.png differ diff --git a/textures/throwing_arrow_teleport.png b/textures/throwing_arrow_teleport.png new file mode 100644 index 0000000..584735b Binary files /dev/null and b/textures/throwing_arrow_teleport.png differ diff --git a/textures/throwing_arrow_teleport_2.png b/textures/throwing_arrow_teleport_2.png new file mode 100644 index 0000000..56192c8 Binary files /dev/null and b/textures/throwing_arrow_teleport_2.png differ diff --git a/textures/throwing_arrow_teleport_back.png b/textures/throwing_arrow_teleport_back.png new file mode 100644 index 0000000..325c203 Binary files /dev/null and b/textures/throwing_arrow_teleport_back.png differ diff --git a/textures/throwing_arrow_teleport_front.png b/textures/throwing_arrow_teleport_front.png new file mode 100644 index 0000000..138f1cf Binary files /dev/null and b/textures/throwing_arrow_teleport_front.png differ diff --git a/textures/throwing_arrow_tnt.png b/textures/throwing_arrow_tnt.png new file mode 100644 index 0000000..c7ee8f1 Binary files /dev/null and b/textures/throwing_arrow_tnt.png differ diff --git a/textures/throwing_arrow_tnt_2.png b/textures/throwing_arrow_tnt_2.png new file mode 100644 index 0000000..3b53ece Binary files /dev/null and b/textures/throwing_arrow_tnt_2.png differ diff --git a/textures/throwing_arrow_tnt_back.png b/textures/throwing_arrow_tnt_back.png new file mode 100644 index 0000000..230bb18 Binary files /dev/null and b/textures/throwing_arrow_tnt_back.png differ diff --git a/textures/throwing_arrow_tnt_front.png b/textures/throwing_arrow_tnt_front.png new file mode 100644 index 0000000..b7252ac Binary files /dev/null and b/textures/throwing_arrow_tnt_front.png differ diff --git a/textures/throwing_arrow_torch.png b/textures/throwing_arrow_torch.png new file mode 100644 index 0000000..1c424e4 Binary files /dev/null and b/textures/throwing_arrow_torch.png differ diff --git a/textures/throwing_arrow_torch_2.png b/textures/throwing_arrow_torch_2.png new file mode 100644 index 0000000..a5800ce Binary files /dev/null and b/textures/throwing_arrow_torch_2.png differ diff --git a/textures/throwing_arrow_torch_back.png b/textures/throwing_arrow_torch_back.png new file mode 100644 index 0000000..3b9fd11 Binary files /dev/null and b/textures/throwing_arrow_torch_back.png differ diff --git a/textures/throwing_arrow_torch_front.png b/textures/throwing_arrow_torch_front.png new file mode 100644 index 0000000..764a263 Binary files /dev/null and b/textures/throwing_arrow_torch_front.png differ diff --git a/textures/throwing_bow_composite.png b/textures/throwing_bow_composite.png new file mode 100644 index 0000000..630af5a Binary files /dev/null and b/textures/throwing_bow_composite.png differ diff --git a/textures/throwing_bow_composite_loaded.png b/textures/throwing_bow_composite_loaded.png new file mode 100644 index 0000000..67bf8e5 Binary files /dev/null and b/textures/throwing_bow_composite_loaded.png differ diff --git a/textures/throwing_bow_royal.png b/textures/throwing_bow_royal.png new file mode 100644 index 0000000..43c20f8 Binary files /dev/null and b/textures/throwing_bow_royal.png differ diff --git a/textures/throwing_bow_royal_loaded.png b/textures/throwing_bow_royal_loaded.png new file mode 100644 index 0000000..3416f2e Binary files /dev/null and b/textures/throwing_bow_royal_loaded.png differ diff --git a/textures/throwing_bow_steel.png b/textures/throwing_bow_steel.png new file mode 100644 index 0000000..0e1d3d1 Binary files /dev/null and b/textures/throwing_bow_steel.png differ diff --git a/textures/throwing_bow_steel_loaded.png b/textures/throwing_bow_steel_loaded.png new file mode 100644 index 0000000..16150a6 Binary files /dev/null and b/textures/throwing_bow_steel_loaded.png differ diff --git a/textures/throwing_bow_wood.png b/textures/throwing_bow_wood.png new file mode 100644 index 0000000..9a6c6da Binary files /dev/null and b/textures/throwing_bow_wood.png differ diff --git a/textures/throwing_bow_wood_loaded.png b/textures/throwing_bow_wood_loaded.png new file mode 100644 index 0000000..251e643 Binary files /dev/null and b/textures/throwing_bow_wood_loaded.png differ diff --git a/textures/throwing_crossbow.png b/textures/throwing_crossbow.png new file mode 100644 index 0000000..f8a400b Binary files /dev/null and b/textures/throwing_crossbow.png differ diff --git a/textures/throwing_crossbow_loaded.png b/textures/throwing_crossbow_loaded.png new file mode 100644 index 0000000..5d2b0c7 Binary files /dev/null and b/textures/throwing_crossbow_loaded.png differ diff --git a/textures/throwing_empty.png b/textures/throwing_empty.png new file mode 100644 index 0000000..6bbd554 Binary files /dev/null and b/textures/throwing_empty.png differ diff --git a/textures/throwing_longbow.png b/textures/throwing_longbow.png new file mode 100644 index 0000000..7bdae2f Binary files /dev/null and b/textures/throwing_longbow.png differ diff --git a/textures/throwing_longbow_loaded.png b/textures/throwing_longbow_loaded.png new file mode 100644 index 0000000..e03299a Binary files /dev/null and b/textures/throwing_longbow_loaded.png differ diff --git a/textures/throwing_sparkle.png b/textures/throwing_sparkle.png new file mode 100644 index 0000000..432786e Binary files /dev/null and b/textures/throwing_sparkle.png differ diff --git a/textures/throwing_sparkle_blue.png b/textures/throwing_sparkle_blue.png new file mode 100644 index 0000000..d4710a3 Binary files /dev/null and b/textures/throwing_sparkle_blue.png differ diff --git a/textures/throwing_sparkle_red.png b/textures/throwing_sparkle_red.png new file mode 100644 index 0000000..59ec68c Binary files /dev/null and b/textures/throwing_sparkle_red.png differ diff --git a/throwing.conf b/throwing.conf new file mode 100755 index 0000000..ed96896 --- /dev/null +++ b/throwing.conf @@ -0,0 +1,33 @@ + +-- Bows +DISABLE_WOODEN_BOW = false +DISABLE_LONGBOW = false +DISABLE_COMPOSITE_BOW = false +DISABLE_STEEL_BOW = false +DISABLE_ROYAL_BOW = false + +-- Crossbows +DISABLE_CROSSBOW = false +DISABLE_ARBALEST = false +DISABLE_AUTOMATED_ARBALEST = false + +-- Special Arrows +DISABLE_TELEPORT_ARROW = false +DISABLE_DIG_ARROW = true -- Deactivated to prevent griefing +DISABLE_BUILD_ARROW = true -- Deactivated to prevent griefing +DISABLE_TNT_ARROW = true -- Deactivated to prevent griefing +DISABLE_FIRE_ARROW = true -- Deactivated to prevent griefing +DISABLE_TORCH_ARROW = false +DISABLE_SHELL_ARROW = true -- Deactivated until crash bug related to this arrow is resolved + +-- Fireworks arrows +DISABLE_FIREWORKS_BLUE_ARROW = false +DISABLE_FIREWORKS_RED_ARROW = false + +-- Normal arrows +DISABLE_STONE_ARROW = false +DISABLE_STEEL_ARROW = false +DISABLE_OBSIDIAN_ARROW = false +DISABLE_DIAMOND_ARROW = false +-- lesser damages to better damages + diff --git a/tnt_arrow.lua b/tnt_arrow.lua new file mode 100755 index 0000000..fcabda9 --- /dev/null +++ b/tnt_arrow.lua @@ -0,0 +1,284 @@ +minetest.register_craftitem("throwing:arrow_tnt", { + description = "TNT arrow", + inventory_image = "throwing_arrow_tnt.png", +}) + +minetest.register_node("throwing:arrow_tnt_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_tnt.png", "throwing_arrow_tnt.png", "throwing_arrow_tnt_back.png", "throwing_arrow_tnt_front.png", "throwing_arrow_tnt_2.png", "throwing_arrow_tnt.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + timer=0, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_tnt_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, +} + +-- TNT functions copied, would be nice to directly call them through an API... + +-- loss probabilities array (one in X will be lost) +local loss_prob = {} + +loss_prob["default:cobble"] = 3 +loss_prob["default:dirt"] = 4 + +local radius = tonumber(minetest.setting_get("tnt_radius") or 3) + +-- Fill a list with data for content IDs, after all nodes are registered +local cid_data = {} +minetest.after(0, function() + for name, def in pairs(minetest.registered_nodes) do + cid_data[minetest.get_content_id(name)] = { + name = name, + drops = def.drops, + flammable = def.groups.flammable, + } + end +end) + +local function rand_pos(center, pos, radius) + pos.x = center.x + math.random(-radius, radius) + pos.z = center.z + math.random(-radius, radius) +end + +local function eject_drops(drops, pos, radius) + local drop_pos = vector.new(pos) + for _, item in pairs(drops) do + local count = item:get_count() + local max = item:get_stack_max() + if count > max then + item:set_count(max) + end + while count > 0 do + if count < max then + item:set_count(count) + end + rand_pos(pos, drop_pos, radius) + local obj = minetest.add_item(drop_pos, item) + if obj then + obj:get_luaentity().collect = true + obj:setacceleration({x=0, y=-10, z=0}) + obj:setvelocity({x=math.random(-3, 3), y=10, + z=math.random(-3, 3)}) + end + count = count - max + end + end +end + +local function add_drop(drops, item) + item = ItemStack(item) + local name = item:get_name() + if loss_prob[name] ~= nil and math.random(1, loss_prob[name]) == 1 then + return + end + + local drop = drops[name] + if drop == nil then + drops[name] = item + else + drop:set_count(drop:get_count() + item:get_count()) + end +end + +local fire_node = {name="fire:basic_flame"} + +local function destroy(drops, pos, cid) + if minetest.is_protected(pos, "") then + return + end + local def = cid_data[cid] + if def and def.flammable then + minetest.set_node(pos, fire_node) + else + minetest.dig_node(pos) + if def then + local node_drops = minetest.get_node_drops(def.name, "") + for _, item in ipairs(node_drops) do + add_drop(drops, item) + end + end + end +end + + +local function calc_velocity(pos1, pos2, old_vel, power) + local vel = vector.direction(pos1, pos2) + vel = vector.normalize(vel) + vel = vector.multiply(vel, power) + + -- Divide by distance + local dist = vector.distance(pos1, pos2) + dist = math.max(dist, 1) + vel = vector.divide(vel, dist) + + -- Add old velocity + vel = vector.add(vel, old_vel) + return vel +end + +local function entity_physics(pos, radius) + -- Make the damage radius larger than the destruction radius + radius = radius * 2 + local objs = minetest.get_objects_inside_radius(pos, radius) + for _, obj in pairs(objs) do + local obj_pos = obj:getpos() + local obj_vel = obj:getvelocity() + local dist = math.max(1, vector.distance(pos, obj_pos)) + + if obj_vel ~= nil then + obj:setvelocity(calc_velocity(pos, obj_pos, + obj_vel, radius * 10)) + end + + local damage = (5 / dist) * radius + obj:set_hp(obj:get_hp() - damage) + end +end + +local function add_effects(pos, radius) + minetest.add_particlespawner({ + amount = 128, + time = 1, + minpos = vector.subtract(pos, radius / 2), + maxpos = vector.add(pos, radius / 2), + minvel = {x=-20, y=-20, z=-20}, + maxvel = {x=20, y=20, z=20}, + minacc = vector.new(), + maxacc = vector.new(), + minexptime = 1, + maxexptime = 3, + minsize = 8, + maxsize = 16, + texture = "tnt_smoke.png", + }) +end + + +local function explode(pos, radius) + local pos = vector.round(pos) + local vm = VoxelManip() + local pr = PseudoRandom(os.time()) + local p1 = vector.subtract(pos, radius) + local p2 = vector.add(pos, radius) + local minp, maxp = vm:read_from_map(p1, p2) + local a = VoxelArea:new({MinEdge = minp, MaxEdge = maxp}) + local data = vm:get_data() + + local drops = {} + local p = {} + + local c_air = minetest.get_content_id("air") + local c_tnt = minetest.get_content_id("tnt:tnt") + local c_tnt_burning = minetest.get_content_id("tnt:tnt_burning") + local c_gunpowder = minetest.get_content_id("tnt:gunpowder") + local c_gunpowder_burning = minetest.get_content_id("tnt:gunpowder_burning") + local c_boom = minetest.get_content_id("tnt:boom") + local c_fire = minetest.get_content_id("fire:basic_flame") + + for z = -radius, radius do + for y = -radius, radius do + local vi = a:index(pos.x + (-radius), pos.y + y, pos.z + z) + for x = -radius, radius do + if (x * x) + (y * y) + (z * z) <= + (radius * radius) + pr:next(-radius, radius) then + local cid = data[vi] + p.x = pos.x + x + p.y = pos.y + y + p.z = pos.z + z + if cid == c_tnt or cid == c_gunpowder then + burn(p) + elseif cid ~= c_tnt_burning and + cid ~= c_gunpowder_burning and + cid ~= c_air and + cid ~= c_fire and + cid ~= c_boom then + destroy(drops, p, cid) + end + end + vi = vi + 1 + end + end + end + + return drops +end + + +local function boom(pos) + minetest.sound_play("tnt_explode", {pos=pos, gain=1.5, max_hear_distance=2*64}) + minetest.set_node(pos, {name="tnt:boom"}) + minetest.get_node_timer(pos):start(0.5) + + local drops = explode(pos, radius) + entity_physics(pos, radius) + eject_drops(drops, pos, radius) + add_effects(pos, radius) +end + +-- Back to the arrow + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x ~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 2) + for k, obj in pairs(objs) do + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + boom(pos) + self.object:remove() + return + end + end + + if node.name ~= "air" then + boom(pos) + self.object:remove() + return + end + end + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} +end + +minetest.register_entity("throwing:arrow_tnt_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_tnt', + recipe = { + {'default:stick', 'tnt:tnt', 'default:bronze_ingot'}, + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_tnt', + recipe = { + {'default:bronze_ingot', 'tnt:tnt', 'default:stick'}, + } +}) diff --git a/tools.lua b/tools.lua new file mode 100755 index 0000000..4eba3c9 --- /dev/null +++ b/tools.lua @@ -0,0 +1,65 @@ +if not DISABLE_WOODEN_BOW then + throwing_register_bow ('bow_wood', 'Wooden bow', {x=1, y=1, z=0.5}, 15, 1.5, 50, false, { + {'', 'default:stick', ''}, + {'farming:string', '', 'default:stick'}, + {'', 'default:stick', ''}, + }) +end + +if not DISABLE_LONGBOW then + throwing_register_bow ('longbow', 'Longbow', {x=1, y=2.5, z=0.5}, 20, 1.5, 100, false, { + {'farming:string', 'group:wood', ''}, + {'farming:string', '', 'group:wood'}, + {'farming:string', 'group:wood', ''}, + }) +end + +if not DISABLE_COMPOSITE_BOW then + throwing_register_bow ('bow_composite', 'Composite bow', {x=1, y=1.4, z=0.5}, 25, 2, 150, false, { + {'farming:string', 'group:wood', ''}, + {'farming:string', '', 'default:steel_ingot'}, + {'farming:string', 'group:wood', ''}, + }) +end + +if not DISABLE_STEEL_BOW then + throwing_register_bow ('bow_steel', 'Steel bow', {x=1, y=1.4, z=0.5}, 30, 2, 250, false, { + {'farming:string', 'default:steel_ingot', ''}, + {'farming:string', '', 'default:steel_ingot'}, + {'farming:string', 'default:steel_ingot', ''}, + }) +end + +if not DISABLE_ROYAL_BOW then + throwing_register_bow ('bow_royal', 'Royal bow', {x=1, y=1.5, z=0.5}, 35, 1, 750, false, { + {'farming:string', 'group:wood', 'default:diamond'}, + {'farming:string', '', 'default:gold_ingot'}, + {'farming:string', 'group:wood', 'default:diamond'}, + }) +end + +--function throwing_register_bow (name, desc, scale, stiffness, reload_time, toughness, is_cross, craft) + +if not DISABLE_CROSSBOW then + throwing_register_bow ('crossbow', 'Crossbow', {x=1, y=1.3, z=0.5}, 40, 5, 80, true, { + {'group:wood', 'farming:string', ''}, + {'default:steel_ingot', 'farming:string', 'group:wood'}, + {'group:wood', 'farming:string', ''}, + }) +end + +if not DISABLE_ARBALEST then + throwing_register_bow ('arbalest', 'Arbalest', {x=1, y=1.3, z=0.5}, 50, 5, 120, true, { + {'default:steel_ingot', 'farming:string', 'default:stick'}, + {'default:steel_ingot', 'farming:string', 'default:steel_ingot'}, + {'default:steel_ingot', 'farming:string', 'default:stick'}, + }) +end + +if not DISABLE_AUTOMATED_ARBALEST then + throwing_register_bow ('arbalest_auto', 'Automated arbalest', {x=1, y=1.3, z=0.5}, 50, 1.5, 60, true, { + {'default:steel_ingot', 'farming:string', 'default:mese_crystal'}, + {'default:steel_ingot', 'farming:string', 'default:steel_ingot'}, + {'default:steel_ingot', 'farming:string', 'default:mese_crystal'}, + }) +end diff --git a/torch_arrow.lua b/torch_arrow.lua new file mode 100755 index 0000000..50899cf --- /dev/null +++ b/torch_arrow.lua @@ -0,0 +1,140 @@ +minetest.register_craftitem("throwing:arrow_torch", { + description = "Torch Arrow", + inventory_image = "throwing_arrow_torch.png", +}) + +minetest.register_node("throwing:arrow_torch_box", { + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + -- Shaft + {-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17}, + --Spitze + {-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17}, + {-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17}, + --Federn + {6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17}, + {7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17}, + {7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17}, + {6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17}, + + {7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17}, + {8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17}, + {8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17}, + {7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17}, + } + }, + tiles = {"throwing_arrow_torch.png", "throwing_arrow_torch.png", "throwing_arrow_torch_back.png", "throwing_arrow_torch_front.png", "throwing_arrow_torch_2.png", "throwing_arrow_torch.png"}, + groups = {not_in_creative_inventory=1}, +}) + +local THROWING_ARROW_ENTITY={ + physical = false, + visual = "wielditem", + visual_size = {x=0.1, y=0.1}, + textures = {"throwing:arrow_torch_box"}, + lastpos={}, + collisionbox = {0,0,0,0,0,0}, + node = "", + player = "", + bow_damage = 0, +} + +THROWING_ARROW_ENTITY.on_step = function(self, dtime) + local newpos = self.object:getpos() + if self.lastpos.x~= nil then + for _, pos in pairs(throwing_get_trajectoire(self, newpos)) do + local node = minetest.get_node(pos) + local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 0.5) + for k, obj in pairs(objs) do + local objpos = obj:getpos() + if throwing_is_player(self.player, obj) or throwing_is_entity(obj) then + if throwing_touch(pos, objpos) then + local puncher = self.object + if self.player and minetest.get_player_by_name(self.player) then + puncher = minetest.get_player_by_name(self.player) + end + local damage = 0.5 + if self.bow_damage and self.bow_damage > 0 then + damage = damage + (self.bow_damage/12) + end + obj:punch(puncher, 1.0, { + full_punch_interval=1.0, + damage_groups={fleshy=damage}, + }, nil) + local toughness = 0.9 + if math.random() < toughness then + if math.random(0,100) % 2 == 0 then -- 50% of chance to drop //MFF (Mg|07/27/15) + minetest.add_item(pos, 'throwing:arrow_torch') + end + else + minetest.add_item(pos, 'default:stick') + end + self.object:remove() + return + end + end + end + + + if node.name == 'air' then + minetest.add_node(pos, {name="throwing:torch_trail"}) + minetest.get_node_timer(pos):start(0.1) + elseif node.name ~= "air" + and not string.find(node.name, "trail") + and not (string.find(node.name, 'grass') and not string.find(node.name, 'dirt')) + and not (string.find(node.name, 'farming:') and not string.find(node.name, 'soil')) + and not string.find(node.name, 'flowers:') + and not string.find(node.name, 'fire:') then + local player = minetest.get_player_by_name(self.player) + if not player then self.object:remove() return end + if node.name ~= "ignore" and not string.find(node.name, "water_") and not string.find(node.name, "lava") + and not string.find(node.name, "torch") and minetest.get_item_group(node.name, "unbreakable") == 0 + and not minetest.is_protected(self.lastpos, self.player) and node.diggable ~= false then + local dir=vector.direction(self.lastpos, pos) + local wall=minetest.dir_to_wallmounted(dir) + minetest.add_node(self.lastpos, {name="default:torch", param2 = wall}) + else + local toughness = 0.9 + if math.random() < toughness then + minetest.add_item(self.lastpos, 'throwing:arrow_torch') + else + minetest.add_item(self.lastpos, 'default:stick') + end + end + self.object:remove() + return + end + self.lastpos={x=pos.x, y=pos.y, z=pos.z} + end + end + self.lastpos={x=newpos.x, y=newpos.y, z=newpos.z} +end + +minetest.register_entity("throwing:arrow_torch_entity", THROWING_ARROW_ENTITY) + +minetest.register_craft({ + output = 'throwing:arrow_torch 4', + recipe = { + {'default:stick', 'default:stick', 'group:coal'}, + } +}) + +minetest.register_craft({ + output = 'throwing:arrow_torch 4', + recipe = { + {'group:coal', 'default:stick', 'default:stick'}, + } +}) + +minetest.register_node("throwing:torch_trail", { + drawtype = "airlike", + light_source = default.LIGHT_MAX-1, + walkable = false, + drop = "", + groups = {dig_immediate=3}, + on_timer = function(pos, elapsed) + minetest.remove_node(pos) + end, +})