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
This commit is contained in:
upsilon 2017-01-12 20:49:42 +01:00
parent e7ae9a01cf
commit a6ce9315b0
3 changed files with 51 additions and 20 deletions

View File

@ -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). whether the arrow hitted a node or an object (you should always check for that).
An object can be a player or a luaentity. An object can be a player or a luaentity.
* Hitter: the ObjectRef of the player who throwed the arrow. * Hitter: the ObjectRef of the player who throwed the arrow.
* When it fails, it should return:
false[, reason]
]] ]]
-- Examples: -- Examples:
@ -74,6 +76,10 @@ function(pos, last_pos, node, object, hitter)
if not node then if not node then
return return
end 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)
``` ```

View File

@ -2,7 +2,7 @@ throwing = {}
throwing.arrows = {} throwing.arrows = {}
local modname = minetest.get_current_modname() throwing.modname = minetest.get_current_modname()
--------- Arrows functions --------- --------- Arrows functions ---------
local function shoot_arrow(itemstack, player) 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 if not player then -- Possible if the player disconnected
return return
end 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 if self.on_hit_sound then
minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8}) minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8})
end end
@ -105,9 +117,10 @@ end
on_hit(pos, last_pos, node, object, hitter) 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. 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. 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) 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} local _groups = {dig_immediate = 3}
if groups then if groups then
@ -115,7 +128,7 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t
_groups[k] = v _groups[k] = v
end end
end end
minetest.register_node(modname..":"..name, { minetest.register_node(throwing.modname..":"..name, {
drawtype = "nodebox", drawtype = "nodebox",
paramtype = "light", paramtype = "light",
node_box = { node_box = {
@ -145,12 +158,12 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
if minetest.setting_getbool("throwing.allow_arrow_placing") and pointed_thing.above then if minetest.setting_getbool("throwing.allow_arrow_placing") and pointed_thing.above then
if not minetest.is_protected(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.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 = modname..":"..name}) minetest.set_node(pointed_thing.above, {name = throwing.modname..":"..name})
itemstack:take_item() itemstack:take_item()
return itemstack return itemstack
else 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 return itemstack
end end
else else
@ -159,29 +172,29 @@ function throwing.register_arrow(name, itemcraft, craft_quantity, description, t
end end
}) })
minetest.register_entity(modname..":"..name.."_entity", { minetest.register_entity(throwing.modname..":"..name.."_entity", {
physical = false, physical = false,
timer = 0, timer = 0,
visual = "wielditem", visual = "wielditem",
visual_size = {x = 0.125, y = 0.125}, visual_size = {x = 0.125, y = 0.125},
textures = {modname..":"..name}, textures = {throwing.modname..":"..name},
collisionbox = {0, 0, 0, 0, 0, 0}, collisionbox = {0, 0, 0, 0, 0, 0},
on_hit = on_hit, on_hit = on_hit,
on_hit_sound = on_hit_sound, on_hit_sound = on_hit_sound,
node = modname..":"..name, node = throwing.modname..":"..name,
player = "", player = "",
on_step = arrow_step on_step = arrow_step
}) })
if itemcraft then if itemcraft then
minetest.register_craft({ minetest.register_craft({
output = modname..":"..name.." "..craft_quantity, output = throwing.modname..":"..name.." "..craft_quantity,
recipe = { recipe = {
{itemcraft, "default:stick", "default:stick"} {itemcraft, "default:stick", "default:stick"}
} }
}) })
minetest.register_craft({ minetest.register_craft({
output = modname..":"..name.." "..craft_quantity, output = throwing.modname..":"..name.." "..craft_quantity,
recipe = { recipe = {
{ "default:stick", "default:stick", itemcraft} { "default:stick", "default:stick", itemcraft}
} }
@ -192,7 +205,7 @@ end
---------- Bows ----------- ---------- Bows -----------
function throwing.register_bow(name, itemcraft, description, texture, groups) function throwing.register_bow(name, itemcraft, description, texture, groups)
minetest.register_tool(modname..":"..name, { minetest.register_tool(throwing.modname..":"..name, {
description = description, description = description,
inventory_image = texture, inventory_image = texture,
on_use = function(itemstack, user, pointed_thing) on_use = function(itemstack, user, pointed_thing)
@ -208,7 +221,7 @@ function throwing.register_bow(name, itemcraft, description, texture, groups)
if itemcraft then if itemcraft then
minetest.register_craft({ minetest.register_craft({
output = modname..":"..name, output = throwing.modname..":"..name,
recipe = { recipe = {
{"farming:cotton", itemcraft, ""}, {"farming:cotton", itemcraft, ""},
{"farming:cotton", "", itemcraft}, {"farming:cotton", "", itemcraft},
@ -219,4 +232,4 @@ function throwing.register_bow(name, itemcraft, description, texture, groups)
end end
dofile(minetest.get_modpath(modname).."/registration.lua") dofile(minetest.get_modpath(throwing.modname).."/registration.lua")

View File

@ -49,7 +49,10 @@ if get_setting("dig_arrow") then
if not node then if not node then
return return
end end
minetest.dig_node(pos) if minetest.is_protected(pos) then
return false, "Area is protected"
end
return minetest.dig_node(pos)
end) end)
end end
@ -83,7 +86,7 @@ end
if get_setting("fire_arrow") then if get_setting("fire_arrow") then
throwing.register_arrow("arrow_fire", "default:torch", 1, "Torch Arrow", 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", {"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 if not node then
return return
end end
@ -91,7 +94,13 @@ if get_setting("fire_arrow") then
minetest.log("warning", "[throwing] BUG: node at last_pos was not air") minetest.log("warning", "[throwing] BUG: node at last_pos was not air")
return return
end 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)
end end
@ -106,6 +115,9 @@ if get_setting("build_arrow") then
minetest.log("warning", "[throwing] BUG: node at last_pos was not air") minetest.log("warning", "[throwing] BUG: node at last_pos was not air")
return return
end 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)
end end