mirror of
https://github.com/minetest-mods/throwing.git
synced 2025-01-09 17:50:25 +01:00
Extend throwing.register_bow, change params order
This commit is contained in:
parent
4930d2f518
commit
000c16d292
13
README.md
13
README.md
@ -39,11 +39,12 @@ Definition: definition table, containing:
|
|||||||
* texture (essential): texture of the bow, shown in inventory.
|
* texture (essential): texture of the bow, shown in inventory.
|
||||||
* groups (optional): groups of the item.
|
* groups (optional): groups of the item.
|
||||||
* uses: number of uses of the bow (default is 50).
|
* uses: number of uses of the bow (default is 50).
|
||||||
* allow_shot (optional): function(player, itemstack):
|
* allow_shot (optional): function(player, itemstack, index):
|
||||||
- player: the player using the bow
|
- player: the player using the bow
|
||||||
- itemstack: the itemstack of the bow
|
- itemstack: the itemstack of the bow
|
||||||
- should return true if the shot can be made, and false otherwise
|
- 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
|
- the default function checks that the arrow to be thrown is a registered arrow
|
||||||
|
- it can return a second return value, which is the new itemstack
|
||||||
* throw_itself (optional): whether the bow should throw itself instead of the arrow next to it in the inventory.
|
* throw_itself (optional): whether the bow should throw itself instead of the arrow next to it in the inventory.
|
||||||
If present, allow_shot is ignored.
|
If present, allow_shot is ignored.
|
||||||
Default is false.
|
Default is false.
|
||||||
@ -69,7 +70,7 @@ Definition: definition table, containing:
|
|||||||
* target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both).
|
* target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both).
|
||||||
* allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area
|
* allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area
|
||||||
* on_hit_sound (optional): sound played when the arrow hits a node or an object.
|
* on_hit_sound (optional): sound played when the arrow hits a node or an object.
|
||||||
* on_hit(pos, last_pos, node, object, hitter, data, self) (optional but very useful): callback function:
|
* on_hit(self, pos, last_pos, node, object, hitter, data) (optional but very useful): callback function:
|
||||||
- pos: the position of the hit node or object.
|
- pos: the position of the hit node or object.
|
||||||
- last_pos: the last air node where the arrow was
|
- last_pos: the last air node where the arrow was
|
||||||
- node and object: hit node or object. Either node or object is nil, depending
|
- node and object: hit node or object. Either node or object is nil, depending
|
||||||
@ -79,15 +80,15 @@ Definition: definition table, containing:
|
|||||||
- self: the arrow entity table (it allows you to hack a lot!)
|
- self: the arrow entity table (it allows you to hack a lot!)
|
||||||
- If it fails, it should return:
|
- If it fails, it should return:
|
||||||
false[, reason]
|
false[, reason]
|
||||||
* on_throw(pos, thrower, next_index, data, self) (optional): callback function: on_throw:
|
* on_throw(self, pos, thrower, itemstack, index, data) (optional): callback function: on_throw:
|
||||||
- pos: the position from where the arrow is throw (which a bit higher than the hitter position)
|
- pos: the position from where the arrow is throw (which a bit higher than the hitter position)
|
||||||
- thrower: an ObjectRef to the thrower player
|
- thrower: an ObjectRef to the thrower player
|
||||||
- next_index: the index 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
|
- data: a data table associated to the entity where you can store what you want
|
||||||
- self: the arrow entity table
|
- self: the arrow entity table
|
||||||
- If the arrow shouldn't be throw, it should return false.
|
- If the arrow shouldn't be thrown, 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_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)
|
* on_hit_fails(self, pos, thrower, data) (optional): callback function called if the hit failed (e.g. because on_hit returned false or because the area was protected)
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Example:
|
-- Example:
|
||||||
|
42
init.lua
42
init.lua
@ -32,14 +32,17 @@ function throwing.spawn_arrow_entity(pos, arrow, player)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function shoot_arrow(itemstack, player, throw_itself)
|
local function shoot_arrow(itemstack, player, throw_itself, new_stack)
|
||||||
local inventory = player:get_inventory()
|
local inventory = player:get_inventory()
|
||||||
local arrow
|
local index = player:get_wield_index()
|
||||||
if throw_itself then
|
if not throw_itself then
|
||||||
arrow = player:get_wielded_item():get_name()
|
if index >= player:get_inventory():get_size("main") then
|
||||||
else
|
return false
|
||||||
arrow = inventory:get_stack("main", player:get_wield_index()+1):get_name()
|
|
||||||
end
|
end
|
||||||
|
index = index + 1
|
||||||
|
end
|
||||||
|
local arrow_stack = inventory:get_stack("main", index)
|
||||||
|
local arrow = arrow_stack:get_name()
|
||||||
|
|
||||||
local playerpos = player:getpos()
|
local playerpos = player:getpos()
|
||||||
local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}
|
local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}
|
||||||
@ -52,7 +55,7 @@ local function shoot_arrow(itemstack, player, throw_itself)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if luaentity.on_throw then
|
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
|
if luaentity:on_throw(pos, player, arrow_stack, index, luaentity.data) == false then
|
||||||
obj:remove()
|
obj:remove()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -72,7 +75,13 @@ local function shoot_arrow(itemstack, player, throw_itself)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not minetest.setting_getbool("creative_mode") then
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
inventory:remove_item("main", arrow)
|
if new_stack then
|
||||||
|
inventory:set_stack("main", index, new_stack)
|
||||||
|
else
|
||||||
|
local stack = inventory:get_stack("main", index)
|
||||||
|
stack:take_item()
|
||||||
|
inventory:set_stack("main", index, stack)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -106,7 +115,7 @@ local function arrow_step(self, dtime)
|
|||||||
player:get_inventory():add_item("main", self.item)
|
player:get_inventory():add_item("main", self.item)
|
||||||
end
|
end
|
||||||
if self.on_hit_fails then
|
if self.on_hit_fails then
|
||||||
self.on_hit_fails(pos, player, self.data, self)
|
self:on_hit_fails(pos, player, self.data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -123,7 +132,7 @@ local function arrow_step(self, dtime)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if self.on_hit then
|
if self.on_hit then
|
||||||
local ret, reason = self.on_hit(pos, self.last_pos, node, obj, player, self.data, self)
|
local ret, reason = self:on_hit(pos, self.last_pos, node, obj, player, self.data)
|
||||||
if ret == false then
|
if ret == false then
|
||||||
if reason then
|
if reason then
|
||||||
logging(": on_hit function failed for reason: "..reason)
|
logging(": on_hit function failed for reason: "..reason)
|
||||||
@ -310,7 +319,10 @@ function throwing.register_bow(name, def)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if not def.allow_shot then
|
if not def.allow_shot then
|
||||||
def.allow_shot = function(player, itemstack)
|
def.allow_shot = function(player, itemstack, index)
|
||||||
|
if index >= player:get_inventory():get_size("main") and not def.throw_itself then
|
||||||
|
return false
|
||||||
|
end
|
||||||
return throwing.is_arrow(itemstack)
|
return throwing.is_arrow(itemstack)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -326,13 +338,15 @@ function throwing.register_bow(name, def)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local index = (def.throw_itself and user:get_wield_index()) or user:get_wield_index()+1
|
||||||
|
local res, new_stack = def.allow_shot(user, user:get_inventory():get_stack("main", index), index)
|
||||||
-- Throw itself?
|
-- Throw itself?
|
||||||
if not def.throw_itself and not def.allow_shot(user, user:get_inventory():get_stack("main", user:get_wield_index()+1)) then
|
if not res then
|
||||||
return itemstack
|
return new_stack or itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Shoot arrow
|
-- Shoot arrow
|
||||||
if shoot_arrow(itemstack, user, def.throw_itself) then
|
if shoot_arrow(itemstack, user, def.throw_itself, new_stack) then
|
||||||
if not minetest.setting_getbool("creative_mode") then
|
if not minetest.setting_getbool("creative_mode") then
|
||||||
itemstack:add_wear(65535 / (def.uses or 50))
|
itemstack:add_wear(65535 / (def.uses or 50))
|
||||||
end
|
end
|
||||||
|
@ -59,7 +59,7 @@ if get_setting("arrow") then
|
|||||||
target = throwing.target_both,
|
target = throwing.target_both,
|
||||||
allow_protected = true,
|
allow_protected = true,
|
||||||
on_hit_sound = "throwing_arrow",
|
on_hit_sound = "throwing_arrow",
|
||||||
on_hit = function(pos, _, node, object, hitter)
|
on_hit = function(self, pos, _, node, object, hitter)
|
||||||
if object then
|
if object then
|
||||||
object:punch(hitter, 1, {
|
object:punch(hitter, 1, {
|
||||||
full_punch_interval = 1,
|
full_punch_interval = 1,
|
||||||
@ -83,7 +83,7 @@ if get_setting("golden_arrow") then
|
|||||||
target = throwing.target_object,
|
target = throwing.target_object,
|
||||||
allow_protected = true,
|
allow_protected = true,
|
||||||
on_hit_sound = "throwing_arrow",
|
on_hit_sound = "throwing_arrow",
|
||||||
on_hit = function(pos, _, _, object, hitter)
|
on_hit = function(self, pos, _, _, object, hitter)
|
||||||
object:punch(hitter, 1, {
|
object:punch(hitter, 1, {
|
||||||
full_punch_interval = 1,
|
full_punch_interval = 1,
|
||||||
damage_groups = {fleshy = 5}
|
damage_groups = {fleshy = 5}
|
||||||
@ -99,7 +99,7 @@ if get_setting("dig_arrow") then
|
|||||||
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
|
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
|
||||||
target = throwing.target_node,
|
target = throwing.target_node,
|
||||||
on_hit_sound = "throwing_dig_arrow",
|
on_hit_sound = "throwing_dig_arrow",
|
||||||
on_hit = function(pos, _, node, _, hitter)
|
on_hit = function(self, pos, _, node, _, hitter)
|
||||||
return minetest.dig_node(pos)
|
return minetest.dig_node(pos)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@ -110,7 +110,7 @@ if get_setting("dig_arrow_admin") then
|
|||||||
description = "Admin Dig Arrow",
|
description = "Admin Dig Arrow",
|
||||||
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
|
tiles = {"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"},
|
||||||
target = throwing.target_node,
|
target = throwing.target_node,
|
||||||
on_hit = function(pos, _, node, _, _)
|
on_hit = function(self, pos, _, node, _, _)
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
end,
|
end,
|
||||||
groups = {not_in_creative_inventory = 1}
|
groups = {not_in_creative_inventory = 1}
|
||||||
@ -124,7 +124,7 @@ if get_setting("teleport_arrow") then
|
|||||||
tiles = {"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"},
|
tiles = {"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"},
|
||||||
allow_protected = true,
|
allow_protected = true,
|
||||||
on_hit_sound = "throwing_teleport_arrow",
|
on_hit_sound = "throwing_teleport_arrow",
|
||||||
on_hit = function(_, last_pos, _, _, hitter)
|
on_hit = function(self, _, last_pos, _, _, hitter)
|
||||||
if minetest.get_node(last_pos).name ~= "air" then
|
if minetest.get_node(last_pos).name ~= "air" 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
|
||||||
@ -145,7 +145,7 @@ if get_setting("fire_arrow") then
|
|||||||
description = "Torch Arrow",
|
description = "Torch Arrow",
|
||||||
tiles = {"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"},
|
tiles = {"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"},
|
||||||
on_hit_sound = "default_place_node",
|
on_hit_sound = "default_place_node",
|
||||||
on_hit = function(pos, last_pos, _, _, hitter)
|
on_hit = function(self, pos, last_pos, _, _, hitter)
|
||||||
if minetest.get_node(last_pos).name ~= "air" then
|
if minetest.get_node(last_pos).name ~= "air" 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
|
||||||
@ -173,7 +173,7 @@ if get_setting("build_arrow") then
|
|||||||
description = "Build Arrow",
|
description = "Build Arrow",
|
||||||
tiles = {"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"},
|
tiles = {"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"},
|
||||||
on_hit_sound = "throwing_build_arrow",
|
on_hit_sound = "throwing_build_arrow",
|
||||||
on_hit = function(_, last_pos, _, _, hitter)
|
on_hit = function(self, _, last_pos, _, _, hitter)
|
||||||
if minetest.get_node(last_pos).name ~= "air" then
|
if minetest.get_node(last_pos).name ~= "air" 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
|
||||||
@ -196,12 +196,16 @@ if get_setting("drop_arrow") then
|
|||||||
tiles = {"throwing_arrow_drop.png", "throwing_arrow_drop.png", "throwing_arrow_drop_back.png", "throwing_arrow_drop_front.png", "throwing_arrow_drop_2.png", "throwing_arrow_drop.png"},
|
tiles = {"throwing_arrow_drop.png", "throwing_arrow_drop.png", "throwing_arrow_drop_back.png", "throwing_arrow_drop_front.png", "throwing_arrow_drop_2.png", "throwing_arrow_drop.png"},
|
||||||
on_hit_sound = "throwing_build_arrow",
|
on_hit_sound = "throwing_build_arrow",
|
||||||
allow_protected = true,
|
allow_protected = true,
|
||||||
on_throw = function(_, thrower, next_index, data)
|
on_throw = function(self, _, thrower, _, index, data)
|
||||||
data.itemstack = thrower:get_inventory():get_stack("main", next_index)
|
local inventory = thrower:get_inventory()
|
||||||
data.index = next_index
|
if index >= inventory:get_size("main") or inventory:get_stack("main", index+1):get_name() == "" then
|
||||||
thrower:get_inventory():set_stack("main", next_index, nil)
|
return false, "nothing to drop"
|
||||||
|
end
|
||||||
|
data.itemstack = inventory:get_stack("main", index+1)
|
||||||
|
data.index = index+1
|
||||||
|
thrower:get_inventory():set_stack("main", index+1, nil)
|
||||||
end,
|
end,
|
||||||
on_hit = function(_, last_pos, _, _, hitter, data)
|
on_hit = function(self, _, last_pos, _, _, hitter, data)
|
||||||
minetest.item_drop(ItemStack(data.itemstack), hitter, last_pos)
|
minetest.item_drop(ItemStack(data.itemstack), hitter, last_pos)
|
||||||
end,
|
end,
|
||||||
on_hit_fails = function(_, thrower, data)
|
on_hit_fails = function(_, thrower, data)
|
||||||
|
Loading…
Reference in New Issue
Block a user