Add toolrank optional support (#21)

* Add toolrank support

* Make bow shot able to level up the bow

* Add requested changes

* Change enable_toolranks to no_toolranks

* Remove the overwritting

* no_toolranks in defs in throwing.register_bow

* Toolranks support: minor changes
Reword documentation in README.md, fix a typo in init.lua and enable toolranks even if def.original_description exists---but do not overwrite it.

* Wait until the arrow hits its target before updating bow toolranks uses

* Add a throwing.toolranks settting to allow globally disabling toolranks

Co-authored-by: upsilon <upsilon@langg.net>
This commit is contained in:
Louis Royer 2020-04-02 16:11:42 +02:00 committed by GitHub
parent e2cb1286f1
commit bd4d040c4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 51 additions and 13 deletions

View File

@ -13,13 +13,19 @@ Mods based on this API:
The settings are the following:
```
# Movement parameters
throwing.velocity_factor = 19
throwing.horizontal_acceleration_factor = -3
throwing.vertical_acceleration = -10
# Whether to allow placing an arrow as a node
throwing.allow_arrow_placing = false
# Minimum time between two shots
throwing.bow_cooldown = 0.2
# Whether to enable toolranks for bows
throwing.toolranks = true
```
## API
@ -49,6 +55,7 @@ Definition: definition table, containing:
* function spawn_arrow_entity(position, arrow, player): defaults to throwing.spawn_arrow_entity
* sound: sound to be played when the bow is used
* delay: delay before throwing the arrow
* no_toolranks: If true, toolranks support is disabled for this item. Defaults to false.
]]
-- Example:

View File

@ -7,6 +7,7 @@ throwing.target_node = 2
throwing.target_both = 3
throwing.modname = minetest.get_current_modname()
local use_toolranks = minetest.get_modpath("toolranks") and minetest.settings:get_bool("throwing.toolranks", true)
--------- Arrows functions ---------
function throwing.is_arrow(itemstack)
@ -27,20 +28,23 @@ function throwing.spawn_arrow_entity(pos, arrow, player)
end
end
local function shoot_arrow(itemstack, player, index, throw_itself, new_stack)
local function shoot_arrow(def, toolranks_data, player, bow_index, throw_itself, new_stack)
local inventory = player:get_inventory()
if not throw_itself then
if index >= player:get_inventory():get_size("main") then
local arrow_index
if throw_itself then
arrow_index = bow_index
else
if bow_index >= player:get_inventory():get_size("main") then
return false
end
index = index + 1
arrow_index = bow_index + 1
end
local arrow_stack = inventory:get_stack("main", index)
local arrow_stack = inventory:get_stack("main", arrow_index)
local arrow = arrow_stack:get_name()
local playerpos = player:get_pos()
local pos = {x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}
local obj = (minetest.registered_items[itemstack:get_name()].spawn_arrow_entity or throwing.spawn_arrow_entity)(pos, arrow, player)
local obj = (def.spawn_arrow_entity or throwing.spawn_arrow_entity)(pos, arrow, player)
local luaentity = obj:get_luaentity()
@ -51,9 +55,10 @@ local function shoot_arrow(itemstack, player, index, throw_itself, new_stack)
end
luaentity.data = {}
luaentity.timer = 0
luaentity.toolranks = toolranks_data -- May be nil if toolranks is disabled
if luaentity.on_throw then
if luaentity:on_throw(pos, player, arrow_stack, index, luaentity.data) == false then
if luaentity:on_throw(pos, player, arrow_stack, arrow_index, luaentity.data) == false then
obj:remove()
return false
end
@ -74,11 +79,11 @@ local function shoot_arrow(itemstack, player, index, throw_itself, new_stack)
if not minetest.settings:get_bool("creative_mode") then
if new_stack then
inventory:set_stack("main", index, new_stack)
inventory:set_stack("main", arrrow_index, new_stack)
else
local stack = inventory:get_stack("main", index)
local stack = inventory:get_stack("main", arrow_index)
stack:take_item()
inventory:set_stack("main", index, stack)
inventory:set_stack("main", arrow_index, stack)
end
end
@ -162,6 +167,16 @@ function throwing.arrow_step(self, dtime)
logging("collided with object at ("..pos.x..","..pos.y..","..pos.z..")")
end
end
-- Toolranks support: update bow uses
if self.toolranks then
local inventory = player:get_inventory()
-- Check that the player did not move the bow
if inventory:get_stack("main", self.toolranks.index):get_name() == self.toolranks.itemstack:get_name() then
local new_itemstack = toolranks.new_afteruse(self.toolranks.itemstack, player, nil, {wear = self.toolranks.wear})
inventory:set_stack("main", self.toolranks.index, new_itemstack)
end
end
end
-- Collision with a node
@ -304,6 +319,9 @@ end
---------- Bows -----------
function throwing.register_bow(name, def)
local enable_toolranks = use_toolranks and not def.no_toolranks
def.name = name
if not def.allow_shot then
def.allow_shot = function(player, itemstack, index)
if index >= player:get_inventory():get_size("main") and not def.throw_itself then
@ -350,9 +368,18 @@ function throwing.register_bow(name, def)
end
-- Shoot arrow
if shoot_arrow(itemstack, user, bow_index, def.throw_itself, new_stack) then
local uses = 65535 / (def.uses or 50)
local toolranks_data
if enable_toolranks then
toolranks_data = {
itemstack = itemstack,
index = bow_index,
wear = uses
}
end
if shoot_arrow(def, toolranks_data, user, bow_index, def.throw_itself, new_stack) then
if not minetest.settings:get_bool("creative_mode") then
itemstack:add_wear(65535 / (def.uses or 50))
itemstack:add_wear(uses)
end
end
@ -370,5 +397,9 @@ function throwing.register_bow(name, def)
end)
return itemstack
end
if enable_toolranks then
def.original_description = def.original_description or def.description
def.description = toolranks.create_description(def.description, 0, 1)
end
minetest.register_tool(name, def)
end

View File

@ -1,3 +1,3 @@
name = throwing
optional_depends = wielded_light
optional_depends = wielded_light, toolranks
description = Throwing library: provides an API for registering throwing and throwable things