initial commit
|
@ -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)
|
||||
|
||||
|
|
@ -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'},
|
||||
}
|
||||
})
|
|
@ -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
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
default
|
||||
farming
|
||||
dye
|
||||
bucket?
|
||||
fire?
|
||||
tnt?
|
|
@ -0,0 +1 @@
|
|||
This mod adds many bows and arrows to Minetest.
|
|
@ -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'},
|
||||
}
|
||||
})
|
|
@ -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"}
|
||||
}
|
||||
})
|
|
@ -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,
|
||||
})
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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'},
|
||||
}
|
||||
})
|
|
@ -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
|
||||
|
|
@ -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'}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,4 @@
|
|||
[Dolphin]
|
||||
PreviewsShown=true
|
||||
Timestamp=2017,9,27,1,19,11
|
||||
Version=4
|
After Width: | Height: | Size: 760 B |
After Width: | Height: | Size: 739 B |
After Width: | Height: | Size: 798 B |
After Width: | Height: | Size: 807 B |
After Width: | Height: | Size: 217 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 217 B |
After Width: | Height: | Size: 210 B |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 221 B |
After Width: | Height: | Size: 215 B |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 262 B |
After Width: | Height: | Size: 271 B |
After Width: | Height: | Size: 268 B |
After Width: | Height: | Size: 306 B |
After Width: | Height: | Size: 222 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 235 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 234 B |
After Width: | Height: | Size: 203 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 216 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 243 B |
After Width: | Height: | Size: 252 B |
After Width: | Height: | Size: 204 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 230 B |
After Width: | Height: | Size: 227 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 219 B |
After Width: | Height: | Size: 213 B |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 220 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 189 B |
After Width: | Height: | Size: 241 B |
After Width: | Height: | Size: 241 B |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 228 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 646 B |
After Width: | Height: | Size: 692 B |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 633 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 581 B |
After Width: | Height: | Size: 622 B |
After Width: | Height: | Size: 673 B |
After Width: | Height: | Size: 677 B |
After Width: | Height: | Size: 178 B |
After Width: | Height: | Size: 661 B |
After Width: | Height: | Size: 674 B |
After Width: | Height: | Size: 190 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 240 B |
|
@ -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
|
||||
|
|
@ -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'},
|
||||
}
|
||||
})
|
|
@ -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
|
|
@ -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,
|
||||
})
|