2015-06-10 17:14:58 +02:00
|
|
|
--~
|
2015-06-03 22:23:21 +02:00
|
|
|
--~ Shot and reload system
|
2015-06-10 17:14:58 +02:00
|
|
|
--~
|
2015-06-03 22:23:21 +02:00
|
|
|
|
|
|
|
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_shoot_arrow (itemstack, player, stiffness, is_cross)
|
2015-07-21 20:59:59 +02:00
|
|
|
if not player then return end
|
2015-06-03 22:23:21 +02:00
|
|
|
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)
|
2015-07-21 20:59:59 +02:00
|
|
|
if not obj then return end
|
2015-06-03 22:23:21 +02:00
|
|
|
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
|
|
|
|
obj:get_luaentity().player = player
|
|
|
|
obj:get_luaentity().inventory = player:get_inventory()
|
|
|
|
obj:get_luaentity().stack = player:get_inventory():get_stack("main", player:get_wield_index()-1)
|
|
|
|
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
|
2015-07-21 20:59:59 +02:00
|
|
|
break
|
2015-06-03 22:23:21 +02:00
|
|
|
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})
|
|
|
|
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,
|
2015-06-10 17:14:58 +02:00
|
|
|
stack_max = 1,
|
2015-06-03 22:23:21 +02:00
|
|
|
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,
|
|
|
|
})
|
2015-06-10 17:14:58 +02:00
|
|
|
|
2015-06-03 22:23:21 +02:00
|
|
|
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)
|
2015-06-10 17:14:58 +02:00
|
|
|
minetest.after(0, throwing_unload, itemstack, user, unloaded, wear)
|
2015-06-03 22:23:21 +02:00
|
|
|
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},
|
|
|
|
})
|
2015-06-10 17:14:58 +02:00
|
|
|
|
2015-06-03 22:23:21 +02:00
|
|
|
minetest.register_craft({
|
|
|
|
output = 'throwing:' .. name,
|
|
|
|
recipe = craft
|
|
|
|
})
|
|
|
|
|
2015-07-23 22:49:30 +02:00
|
|
|
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
|
|
|
|
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
|
2015-06-03 22:23:21 +02:00
|
|
|
minetest.register_craft({
|
|
|
|
output = 'throwing:' .. name,
|
2015-07-23 22:49:30 +02:00
|
|
|
recipe = rev_craft
|
2015-06-03 22:23:21 +02:00
|
|
|
})
|
|
|
|
end
|