From 307b2d60e67b19f87be334cccc0719e6d24ebe5e Mon Sep 17 00:00:00 2001 From: upsilon Date: Tue, 17 Jan 2017 19:03:53 +0100 Subject: [PATCH] Improve API again --- README.md | 55 ++++++++++++++++++++++++++++--------------------------- init.lua | 22 ++++++++++++++-------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 9dccab1..d6659d8 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,11 @@ Definition: definition table, containing: ]] -- Example: -throwing.register_bow("bow_stone", "default:cobble", "Stone Bow", "throwing_bow_stone.png") +throwing.register_bow("bow_wood", { + itemcraft = "default:wood", + description = "Wooden Bow", + texture = "throwing_bow_wood.png" +}) itemcraft, craft_quantity, description, tiles, on_hit_sound, on_hit[, on_throw[, groups]] function throwing.register_arrow(name, definition table) @@ -50,45 +54,42 @@ Definition: definition table, containing: * tiles (essential): tiles of the arrow. * target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both). * on_hit_sound (optional): sound played when the arrow hits a node or an object. - * on_hit (must exist, will crash if nil): callback function: on_hit(pos, last_pos, node, object, hitter, self): + * on_hit(pos, last_pos, node, object, hitter, data, self) (must exist, will crash if nil): callback function: - pos: the position of the hit node or object. - last_pos: the last air node where the arrow was - node and object: hit node or object. Either node or object is nil, depending whether the arrow hit a node or an object. - hitter: an ObjectRef to the thrower player. + - data: a data table associated to the entity where you can store what you want - self: the arrow entity table (it allows you to hack a lot!) - If it fails, it should return: false[, reason] - * on_throw (optional): callback function: on_throw(pos, thrower, next_itemstack, self): + * on_throw(pos, thrower, next_index, data, self) (optional): callback function: on_throw: - pos: the position from where the arrow is throw (which a bit higher than the hitter position) - thrower: an ObjectRef to the thrower player - - next_itemstack: the ItemStack next to the arrow in the "main" inventory + - next_index: the index next to the arrow in the "main" inventory + - data: a data table associated to the entity where you can store what you want + - self: the arrow entity table - If the arrow shouldn't be throw, it should return false. * on_throw_sound (optional, there is a default sound, specify "" for no sound): sound to be played when the arrow is throw + * on_hit_fails(pos, thrower, data, self) (optional): callback function called if the hit failed (e.g. because on_hit returned false or because the area was protected) ]] --- Examples: -throwing.register_arrow("arrow_gold", "default:gold_ingot", 16, "Golden Arrow", -{"throwing_arrow_gold.png", "throwing_arrow_gold.png", "throwing_arrow_gold_back.png", "throwing_arrow_gold_front.png", "throwing_arrow_gold_2.png", "throwing_arrow_gold.png"}, "throwing_arrow", -function(pos, last_pos, node, object, hitter) - if not object then - return - end - object:punch(minetest.get_player_by_name(hitter), 1, { - full_punch_interval = 1, - damage_groups = {fleshy = 5} +-- Example: +if get_setting("arrow") then + throwing.register_arrow("arrow", { + itemcraft = "default:steel_ingot", + craft_quantity = 16, + description = "Arrow", + tiles = {"throwing_arrow.png", "throwing_arrow.png", "throwing_arrow_back.png", "throwing_arrow_front.png", "throwing_arrow_2.png", "throwing_arrow.png"}, + target = throwing.target_object, + on_hit_sound = "throwing_arrow", + on_hit = function(pos, _, _, object, hitter) + object:punch(hitter, 1, { + full_punch_interval = 1, + damage_groups = {fleshy = 3} + }) + end }) -end) -throwing.register_arrow("arrow_build", "default:obsidian_glass", 1, "Build Arrow", -{"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"}, "throwing_build_arrow", -function(pos, last_pos, node, object, hitter) - if not node then - return - end - - 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 ``` diff --git a/init.lua b/init.lua index 23371f7..35d4225 100644 --- a/init.lua +++ b/init.lua @@ -10,8 +10,9 @@ 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 player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow then + 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") @@ -20,7 +21,7 @@ local function shoot_arrow(itemstack, player) luaentity.player = player:get_player_name() if luaentity.on_throw then - if luaentity.on_throw(pos, player, luaentity) == false then + if luaentity.on_throw(pos, player, player:get_wield_index()+2, luaentity.data, luaentity) == false then return false end end @@ -39,7 +40,7 @@ local function shoot_arrow(itemstack, player) end if not minetest.setting_getbool("creative_mode") then - player:get_inventory():remove_item("main", arrow) + inventory:remove_item("main", arrow) end return true @@ -71,15 +72,18 @@ local function arrow_step(self, dtime) return end - local function put_arrow_back() + local function hit_failed() if not minetest.setting_getbool("creative_mode") then player:get_inventory():add_item("main", self.node) end + if self.on_hit_fails then + self.on_hit_fails(pos, player, self.data, self) + end end if not self.last_pos then logging("hitted a node during its first call to the step function") - put_arrow_back() + hit_failed() return end @@ -89,7 +93,7 @@ local function arrow_step(self, dtime) return end - local ret, reason = self.on_hit(pos, self.last_pos, node, obj, player, self) + local ret, reason = self.on_hit(pos, self.last_pos, node, obj, player, self.data, self) if ret == false then if reason then logging(": on_hit function failed for reason: "..reason) @@ -97,7 +101,7 @@ local function arrow_step(self, dtime) logging(": on_hit function failed") end - put_arrow_back() + hit_failed() return end @@ -237,9 +241,11 @@ function throwing.register_arrow(name, def) on_throw_sound = def.on_throw_sound, on_throw = def.on_throw, target = def.target, + on_hit_fails = def.on_hit_fails, node = throwing.modname..":"..name, player = "", - on_step = arrow_step + on_step = arrow_step, + data = {} }) if def.itemcraft then