From a6ce9315b0278f9b2047989ed1a49d76d58e7fc3 Mon Sep 17 00:00:00 2001 From: upsilon Date: Thu, 12 Jan 2017 20:49:42 +0100 Subject: [PATCH] Many things: * Use global variable throwing.modname instead of local modname * Use minetest.place_node instead of minetest.set_node for torch arrow and build arrow * Add an error return value to the on_hit function --- README.md | 8 +++++++- init.lua | 43 ++++++++++++++++++++++++++++--------------- registration.lua | 20 ++++++++++++++++---- 3 files changed, 51 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index fb26499..044f998 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ On_hit: callback function: on_hit(pos, last_pos, node, object, hitter) where: whether the arrow hitted a node or an object (you should always check for that). An object can be a player or a luaentity. * Hitter: the ObjectRef of the player who throwed the arrow. + * When it fails, it should return: + false[, reason] ]] -- Examples: @@ -74,6 +76,10 @@ function(pos, last_pos, node, object, hitter) if not node then return end - minetest.set_node(last_pos, {name="default:obsidian_glass"}) + + if minetest.is_protected(last_pos) then + return false, "Area is protected" + end + return minetest.place_node(last_pos, {name="default:obsidian_glass"}) end) ``` diff --git a/init.lua b/init.lua index df79835..f1fa7e2 100644 --- a/init.lua +++ b/init.lua @@ -2,7 +2,7 @@ throwing = {} throwing.arrows = {} -local modname = minetest.get_current_modname() +throwing.modname = minetest.get_current_modname() --------- Arrows functions --------- local function shoot_arrow(itemstack, player) @@ -58,7 +58,19 @@ local function arrow_step(self, dtime) if not player then -- Possible if the player disconnected return end - self.on_hit(pos, self.last_pos, node, obj, player) + local ret, reason = self.on_hit(pos, self.last_pos, node, obj, player) + if ret == false then + if reason then + logging(": on_hit function failed for reason: "..reason, "warning") + else + logging(": on_hit function failed", "warning") + end + + if not minetest.setting_getbool("creative_mode") then + player:get_inventory():add_item("main", self.node) + end + end + if self.on_hit_sound then minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8}) end @@ -105,9 +117,10 @@ end on_hit(pos, last_pos, node, object, hitter) Either node or object is nil, depending whether the arrow collided with an object (luaentity or player) or with a node. No log message is needed in this function (a generic log message is automatically emitted), except on error or warning. +Should return false or false, reason on failure. ]] function throwing.register_arrow(name, itemcraft, craft_quantity, description, tiles, on_hit_sound, on_hit, groups) - table.insert(throwing.arrows, modname..":"..name) + table.insert(throwing.arrows, throwing.modname..":"..name) local _groups = {dig_immediate = 3} if groups then @@ -115,7 +128,7 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t _groups[k] = v end end - minetest.register_node(modname..":"..name, { + minetest.register_node(throwing.modname..":"..name, { drawtype = "nodebox", paramtype = "light", node_box = { @@ -145,12 +158,12 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t on_place = function(itemstack, placer, pointed_thing) if minetest.setting_getbool("throwing.allow_arrow_placing") and pointed_thing.above then if not minetest.is_protected(pointed_thing.above) then - minetest.log("action", "Player "..placer:get_player_name().." placed arrow "..modname..":"..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") - minetest.set_node(pointed_thing.above, {name = modname..":"..name}) + minetest.log("action", "Player "..placer:get_player_name().." placed arrow "..throwing.modname..":"..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") + minetest.set_node(pointed_thing.above, {name = throwing.modname..":"..name}) itemstack:take_item() return itemstack else - minetest.log("warning", "Player "..placer:get_player_name().." tried to place arrow "..modname..":"..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") + minetest.log("warning", "Player "..placer:get_player_name().." tried to place arrow "..throwing.modname..":"..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")") return itemstack end else @@ -159,29 +172,29 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t end }) - minetest.register_entity(modname..":"..name.."_entity", { + minetest.register_entity(throwing.modname..":"..name.."_entity", { physical = false, timer = 0, visual = "wielditem", visual_size = {x = 0.125, y = 0.125}, - textures = {modname..":"..name}, + textures = {throwing.modname..":"..name}, collisionbox = {0, 0, 0, 0, 0, 0}, on_hit = on_hit, on_hit_sound = on_hit_sound, - node = modname..":"..name, + node = throwing.modname..":"..name, player = "", on_step = arrow_step }) if itemcraft then minetest.register_craft({ - output = modname..":"..name.." "..craft_quantity, + output = throwing.modname..":"..name.." "..craft_quantity, recipe = { {itemcraft, "default:stick", "default:stick"} } }) minetest.register_craft({ - output = modname..":"..name.." "..craft_quantity, + output = throwing.modname..":"..name.." "..craft_quantity, recipe = { { "default:stick", "default:stick", itemcraft} } @@ -192,7 +205,7 @@ end ---------- Bows ----------- function throwing.register_bow(name, itemcraft, description, texture, groups) - minetest.register_tool(modname..":"..name, { + minetest.register_tool(throwing.modname..":"..name, { description = description, inventory_image = texture, on_use = function(itemstack, user, pointed_thing) @@ -208,7 +221,7 @@ function throwing.register_bow(name, itemcraft, description, texture, groups) if itemcraft then minetest.register_craft({ - output = modname..":"..name, + output = throwing.modname..":"..name, recipe = { {"farming:cotton", itemcraft, ""}, {"farming:cotton", "", itemcraft}, @@ -219,4 +232,4 @@ function throwing.register_bow(name, itemcraft, description, texture, groups) end -dofile(minetest.get_modpath(modname).."/registration.lua") +dofile(minetest.get_modpath(throwing.modname).."/registration.lua") diff --git a/registration.lua b/registration.lua index 13d8213..8534f38 100644 --- a/registration.lua +++ b/registration.lua @@ -49,7 +49,10 @@ if get_setting("dig_arrow") then if not node then return end - minetest.dig_node(pos) + if minetest.is_protected(pos) then + return false, "Area is protected" + end + return minetest.dig_node(pos) end) end @@ -83,7 +86,7 @@ end if get_setting("fire_arrow") then throwing.register_arrow("arrow_fire", "default:torch", 1, "Torch Arrow", {"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"}, "default_place_node", - function(_, last_pos, node, _, _) + function(_, last_pos, node, _, hitter) if not node then return end @@ -91,7 +94,13 @@ if get_setting("fire_arrow") then minetest.log("warning", "[throwing] BUG: node at last_pos was not air") return end - minetest.set_node(last_pos, {name="default:torch"}) + + local under_node_name = minetest.get_node({x = last_pos.x, y = last_pos.y-1, z = last_pos.z}).name + if under_node_name ~= "air" and name ~= "ignore" then + minetest.place_node(last_pos, {name="default:torch"}) + else + return false, "Attached node default:torch can not be placed" + end end) end @@ -106,6 +115,9 @@ if get_setting("build_arrow") then minetest.log("warning", "[throwing] BUG: node at last_pos was not air") return end - minetest.set_node(last_pos, {name="default:obsidian_glass"}) + if minetest.is_protected(last_pos) then + return false, "Area is protected" + end + return minetest.place_node(last_pos, {name="default:obsidian_glass"}) end) end