VoxeLibre/mods/ITEMS/mcl_throwing/init.lua

224 lines
7 KiB
Lua
Raw Normal View History

2017-02-14 23:18:23 +01:00
mcl_throwing = {}
2017-01-16 23:11:04 +01:00
dofile(minetest.get_modpath("mcl_throwing").."/arrow.lua")
dofile(minetest.get_modpath("mcl_throwing").."/throwable.lua")
2015-06-29 19:55:56 +02:00
2017-01-24 02:31:49 +01:00
local arrows = {
["mcl_throwing:arrow"] = "mcl_throwing:arrow_entity",
2015-06-29 19:55:56 +02:00
}
2017-01-16 23:11:04 +01:00
local GRAVITY = 9.81
2017-05-27 00:04:11 +02:00
local bow_durability = 385
mcl_throwing.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damage)
local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, arrows[arrow_item])
if power == nil then
power = 19
end
if damage == nil then
damage = 3
end
obj:setvelocity({x=dir.x*power, y=dir.y*power, z=dir.z*power})
obj:setacceleration({x=dir.x*-3, y=-GRAVITY, z=dir.z*-3})
obj:setyaw(yaw-math.pi/2)
local le = obj:get_luaentity()
le._shooter = shooter
le._damage = damage
le._startpos = pos
minetest.sound_play("mcl_throwing_bow_shoot", {pos=pos})
if shooter ~= nil then
if obj:get_luaentity().player == "" then
obj:get_luaentity().player = shooter
end
obj:get_luaentity().node = shooter:get_inventory():get_stack("main", 1):get_name()
end
return obj
end
2017-02-21 22:18:27 +01:00
local get_arrow = function(player)
local inv = player:get_inventory()
2017-02-21 22:18:27 +01:00
local arrow_stack, arrow_stack_id
for i=1, inv:get_size("main") do
local it = inv:get_stack("main", i)
if not it:is_empty() and minetest.get_item_group(it:get_name(), "ammo_bow") ~= 0 then
arrow_stack = it
arrow_stack_id = i
break
end
end
2017-02-21 22:18:27 +01:00
return arrow_stack, arrow_stack_id
end
local player_shoot_arrow = function(itemstack, player, power, damage)
2017-02-21 22:18:27 +01:00
local arrow_stack, arrow_stack_id = get_arrow(player)
local arrow_itemstring
if not minetest.setting_getbool("creative_mode") then
if not arrow_stack then
return false
2015-06-29 19:55:56 +02:00
end
2017-02-21 22:18:27 +01:00
arrow_itemstring = arrow_stack:get_name()
arrow_stack:take_item()
2017-02-21 22:18:27 +01:00
local inv = player:get_inventory()
inv:set_stack("main", arrow_stack_id, arrow_stack)
end
local playerpos = player:getpos()
local dir = player:get_look_dir()
local yaw = player:get_look_horizontal()
if not arrow_itemstring then
arrow_itemstring = "mcl_throwing:arrow"
2015-06-29 19:55:56 +02:00
end
mcl_throwing.shoot_arrow(arrow_itemstring, {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, dir, yaw, player, power, damage)
return true
2015-06-29 19:55:56 +02:00
end
local powerup_function = function(nextbow)
return function(itemstack, placer, pointed_thing)
-- Use pointed node's on_rightclick function first, if present
if pointed_thing.type == "node" then
local node = minetest.get_node(pointed_thing.under)
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
end
end
end
-- Check for arrow or Creative Mode
if minetest.setting_getbool("creative_mode") or get_arrow(placer) ~= nil then
2017-02-21 22:18:27 +01:00
local wear = itemstack:get_wear()
itemstack:replace(nextbow)
itemstack:set_wear(wear)
end
2015-06-29 19:55:56 +02:00
return itemstack
end
end
minetest.register_tool("mcl_throwing:bow", {
description = "Bow",
2017-03-12 02:20:33 +01:00
_doc_items_longdesc = "Bows are ranged weapons to shoot arrows at your foes.",
2017-05-26 23:51:29 +02:00
_doc_items_usagehelp = [[To use the bow, you first need to have at least one arrow anywhere in your inventory (unless in Creative Mode). Rightclick one to three times to charge the bow. Leftclick to shoot.
The arrow speed and damage increase with the charge level:
Low charge: 1 damage
Medium charge: 2 damage
High charge: 4-5 damage (20% chance for 5 damage)]],
2017-05-27 00:04:11 +02:00
_doc_items_durability = bow_durability,
inventory_image = "mcl_throwing_bow.png",
stack_max = 1,
2017-05-27 00:05:50 +02:00
-- Trick to disable melee damage to entities.
-- FIXME: The bows is still able to dig like the hand for some reason. :-(
-- Range not set to 0 (unlike the others) so it can be placed into item frames
range = 1,
on_place = powerup_function("mcl_throwing:bow_0"),
on_secondary_use = powerup_function("mcl_throwing:bow_0"),
groups = {weapon=1,weapon_ranged=1},
2015-06-29 19:55:56 +02:00
})
2017-01-16 23:11:04 +01:00
minetest.register_tool("mcl_throwing:bow_0", {
2015-06-29 19:55:56 +02:00
description = "Bow",
_doc_items_create_entry = false,
2017-01-16 23:11:04 +01:00
inventory_image = "mcl_throwing_bow_0.png",
stack_max = 1,
range = 0, -- Pointing range to 0 to prevent punching with bow :D
2017-02-14 16:35:25 +01:00
groups = {not_in_creative_inventory=1, not_in_craft_guide=1},
on_place = powerup_function("mcl_throwing:bow_1"),
on_secondary_use = powerup_function("mcl_throwing:bow_1"),
on_use = function(itemstack, user, pointed_thing)
local wear = itemstack:get_wear()
itemstack:replace("mcl_throwing:bow")
itemstack:set_wear(wear)
if player_shoot_arrow(itemstack, user, 4, 1) then
if not minetest.setting_getbool("creative_mode") then
2017-05-27 00:04:11 +02:00
itemstack:add_wear(65535/bow_durability)
end
end
return itemstack
end,
2015-06-29 19:55:56 +02:00
})
2017-01-16 23:11:04 +01:00
minetest.register_tool("mcl_throwing:bow_1", {
2015-06-29 19:55:56 +02:00
description = "Bow",
_doc_items_create_entry = false,
2017-01-16 23:11:04 +01:00
inventory_image = "mcl_throwing_bow_1.png",
stack_max = 1,
range = 0,
2017-02-14 16:35:25 +01:00
groups = {not_in_creative_inventory=1, not_in_craft_guide=1},
on_place = powerup_function("mcl_throwing:bow_2"),
on_secondary_use = powerup_function("mcl_throwing:bow_2"),
on_use = function(itemstack, user, pointed_thing)
local wear = itemstack:get_wear()
itemstack:replace("mcl_throwing:bow")
itemstack:set_wear(wear)
if player_shoot_arrow(itemstack, user, 16, 2) then
if not minetest.setting_getbool("creative_mode") then
2017-05-27 00:04:11 +02:00
itemstack:add_wear(65535/bow_durability)
end
end
return itemstack
end,
2015-06-29 19:55:56 +02:00
})
2017-01-16 23:11:04 +01:00
minetest.register_tool("mcl_throwing:bow_2", {
2015-06-29 19:55:56 +02:00
description = "Bow",
_doc_items_create_entry = false,
2017-01-16 23:11:04 +01:00
inventory_image = "mcl_throwing_bow_2.png",
stack_max = 1,
range = 0,
2017-02-14 16:35:25 +01:00
groups = {not_in_creative_inventory=1, not_in_craft_guide=1},
2015-06-29 19:55:56 +02:00
on_use = function(itemstack, user, pointed_thing)
2017-01-24 02:31:49 +01:00
local wear = itemstack:get_wear()
2017-01-16 23:11:04 +01:00
itemstack:replace("mcl_throwing:bow")
2017-02-21 22:18:27 +01:00
itemstack:set_wear(wear)
local r = math.random(1,5)
local damage
-- Damage and range have been nerfed because the arrow charges very quickly
-- TODO: Use Minecraft damage and range (9-10 @ ca. 53 m/s)
if r == 1 then
-- 20% chance to do more damage
damage = 5
else
damage = 4
end
if player_shoot_arrow(itemstack, user, 26, damage) then
2015-06-29 19:55:56 +02:00
if not minetest.setting_getbool("creative_mode") then
2017-05-27 00:04:11 +02:00
itemstack:add_wear(65535/bow_durability)
2015-06-29 19:55:56 +02:00
end
end
return itemstack
end,
})
minetest.register_craft({
2017-01-16 23:11:04 +01:00
output = 'mcl_throwing:bow',
2015-06-29 19:55:56 +02:00
recipe = {
2017-02-01 17:59:15 +01:00
{'', 'mcl_core:stick', 'mcl_mobitems:string'},
{'mcl_core:stick', '', 'mcl_mobitems:string'},
{'', 'mcl_core:stick', 'mcl_mobitems:string'},
2015-06-29 19:55:56 +02:00
}
})
2017-01-10 01:59:21 +01:00
minetest.register_craft({
2017-01-16 23:11:04 +01:00
output = 'mcl_throwing:bow',
2017-01-10 01:59:21 +01:00
recipe = {
2017-02-01 17:59:15 +01:00
{'mcl_mobitems:string', 'mcl_core:stick', ''},
{'mcl_mobitems:string', '', 'mcl_core:stick'},
{'mcl_mobitems:string', 'mcl_core:stick', ''},
2017-01-10 01:59:21 +01:00
}
})
2015-06-29 19:55:56 +02:00
2017-01-10 06:43:07 +01:00
minetest.register_craft({
type = "fuel",
2017-01-16 23:11:04 +01:00
recipe = "mcl_throwing:bow",
2017-01-10 06:43:07 +01:00
burntime = 15,
})
-- Add entry aliases for the Help
if minetest.get_modpath("doc") then
doc.add_entry_alias("tools", "mcl_throwing:bow", "tools", "mcl_throwing:bow_0")
doc.add_entry_alias("tools", "mcl_throwing:bow", "tools", "mcl_throwing:bow_1")
doc.add_entry_alias("tools", "mcl_throwing:bow", "tools", "mcl_throwing:bow_2")
end