From 1778b89597ddbf7a686780eb59cda1b400de8ad1 Mon Sep 17 00:00:00 2001 From: upsilon Date: Tue, 20 Jun 2017 16:23:04 +0200 Subject: [PATCH] Add an allow_shot field to throwing.register_bow definition table And make the throwing.throw_arrow function able to throw any item --- README.md | 5 ++++ init.lua | 89 +++++++++++++++++++++++++++++++++---------------------- 2 files changed, 59 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 5e8581e..3a12fe1 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,11 @@ Definition: definition table, containing: * description (highly recommended): description of the bow. * texture (essential): texture of the bow, shown in inventory. * groups (optional): groups of the item. + * allow_shot (optional): function(player, itemstack): + - player: the player using the bow + - itemstack: the itemstack of the bow + - should return true if the shot can be made, and false otherwise + - default for this is function(player, itemstack) return throwing.is_arrow(itemstack) end ]] -- Example: diff --git a/init.lua b/init.lua index 6bb8b67..4b5a19c 100644 --- a/init.lua +++ b/init.lua @@ -9,47 +9,58 @@ throwing.target_both = 3 throwing.modname = minetest.get_current_modname() --------- Arrows functions --------- -local function shoot_arrow(itemstack, player) - local inventory = player:get_inventory() - for _,arrow in ipairs(throwing.arrows) do - if inventory:get_stack("main", player:get_wield_index()+1):get_name() == arrow then - local playerpos = player:getpos() - local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z} - local obj = minetest.add_entity(pos, arrow.."_entity") - - local luaentity = obj:get_luaentity() - luaentity.player = player:get_player_name() - - if luaentity.on_throw then - if luaentity.on_throw(pos, player, ((player:get_wield_index()+1) % inventory:get_size("main")) + 1, luaentity.data, luaentity) == false then - obj:remove() - return false - end - end - - local dir = player:get_look_dir() - local velocity_factor = tonumber(minetest.setting_get("throwing.velocity_factor")) or 19 - local horizontal_acceleration_factor = tonumber(minetest.setting_get("throwing.horizontal_acceleration_factor")) or -3 - local vertical_acceleration = tonumber(minetest.setting_get("throwing.vertical_acceleration")) or -10 - - obj:setvelocity({x=dir.x*velocity_factor, y=dir.y*velocity_factor, z=dir.z*velocity_factor}) - obj:setacceleration({x=dir.x*horizontal_acceleration_factor, y=vertical_acceleration, z=dir.z*horizontal_acceleration_factor}) - obj:setyaw(player:get_look_horizontal()-math.pi/2) - - if luaentity.on_throw_sound ~= "" then - minetest.sound_play(luaentity.on_throw_sound or "throwing_sound", {pos=playerpos, gain = 0.5}) - end - - if not minetest.setting_getbool("creative_mode") then - inventory:remove_item("main", arrow) - end - +function throwing.is_arrow(itemstack) + for _, arrow in ipairs(throwing.arrows) do + if (type(itemstack) == "string" and itemstack or itemstack:get_name()) == arrow then return true end end return false end +local function shoot_arrow(itemstack, player) + local inventory = player:get_inventory() + local arrow = inventory:get_stack("main", player:get_wield_index()+1):get_name() + + local playerpos = player:getpos() + local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z} + local obj + if throwing.is_arrow(arrow) then + obj = minetest.add_entity(pos, arrow.."_entity") + else + obj = minetest.add_entity(pos, "__builtin:item", arrow) + end + + local luaentity = obj:get_luaentity() + luaentity.player = player:get_player_name() + + if luaentity.on_throw then + if luaentity.on_throw(pos, player, ((player:get_wield_index()+1) % inventory:get_size("main")) + 1, luaentity.data, luaentity) == false then + obj:remove() + return false + end + end + + local dir = player:get_look_dir() + local velocity_factor = tonumber(minetest.setting_get("throwing.velocity_factor")) or 19 + local horizontal_acceleration_factor = tonumber(minetest.setting_get("throwing.horizontal_acceleration_factor")) or -3 + local vertical_acceleration = tonumber(minetest.setting_get("throwing.vertical_acceleration")) or -10 + + obj:setvelocity({x=dir.x*velocity_factor, y=dir.y*velocity_factor, z=dir.z*velocity_factor}) + obj:setacceleration({x=dir.x*horizontal_acceleration_factor, y=vertical_acceleration, z=dir.z*horizontal_acceleration_factor}) + obj:setyaw(player:get_look_horizontal()-math.pi/2) + + if luaentity.on_throw_sound ~= "" then + minetest.sound_play(luaentity.on_throw_sound or "throwing_sound", {pos=playerpos, gain = 0.5}) + end + + if not minetest.setting_getbool("creative_mode") then + player:get_inventory():remove_item("main", arrow) + end + + return true +end + local function arrow_step(self, dtime) self.timer = self.timer + dtime local pos = self.object:getpos() @@ -269,10 +280,18 @@ end ---------- Bows ----------- function throwing.register_bow(name, def) + if not def.allow_shot then + def.allow_shot = function(player, itemstack) + return throwing.is_arrow(itemstack) + end + end minetest.register_tool(throwing.modname..":"..name, { description = def.description, inventory_image = def.texture, on_use = function(itemstack, user, pointed_thing) + if not def.allow_shot(user, user:get_inventory():get_stack("main", user:get_wield_index()+1)) then + return itemstack + end if shoot_arrow(itemstack, user, pointed_thing) then if not minetest.setting_getbool("creative_mode") then itemstack:add_wear(65535/30)