diff --git a/toolranks/.github/workflows/build.yml b/toolranks/.github/workflows/build.yml new file mode 100644 index 0000000..a2d63a0 --- /dev/null +++ b/toolranks/.github/workflows/build.yml @@ -0,0 +1,13 @@ +name: Build +on: [push, pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: apt + run: sudo apt-get install -y luarocks + - name: luacheck install + run: luarocks install --local luacheck + - name: luacheck run + run: $HOME/.luarocks/bin/luacheck ./ diff --git a/toolranks/.luacheckrc b/toolranks/.luacheckrc new file mode 100644 index 0000000..560847f --- /dev/null +++ b/toolranks/.luacheckrc @@ -0,0 +1,18 @@ +unused_args = false +allow_defined_top = true + +globals = { + "minetest", +} + +read_globals = { + string = {fields = {"split"}}, + table = {fields = {"copy", "getn"}}, + + -- Builtin + "vector", "ItemStack", + "dump", "DIR_DELIM", "VoxelArea", "Settings", + + -- MTG + "default", "sfinv", "creative", +} diff --git a/toolranks/README.md b/toolranks/README.md index 7e658d4..4f30c9f 100644 --- a/toolranks/README.md +++ b/toolranks/README.md @@ -1,14 +1,27 @@ -# minetest-toolranks +# minetest-toolranks [toolranks] + Minetest tool ranks mod -Tool gains levels for digging nodes. Higher level tools take longer to -wear out. +Tools gain levels for digging nodes. Higher level tools dig faster and take longer to wear out. ## Are you a mod developer? + Does one of your mods add new tools? -If so, to support this mod, check if it is loaded with -```minetest.get_modpath("toolranks")``` -and then replace all after_use definitions with toolranks.new_afteruse. -Optionaly, you can also replace tools description with -```toolranks.create_description("Tool Name", 0, 1)``` -and then set original_description to your tools name. +If so, to support this mod, add this code to your mod, after your tool's code: + +```lua +if minetest.get_modpath("toolranks") then + minetest.override_item("mymod:mytool", { + original_description = "My Tool", + description = toolranks.create_description("My Tool"), + after_use = toolranks.new_afteruse + }) + end +end +``` + +Or alternatively, you can use the helper function: + +```lua +toolranks.add_tool("mymod:mytool") +``` diff --git a/toolranks/depends.txt b/toolranks/depends.txt index 436cd47..4ad96d5 100644 --- a/toolranks/depends.txt +++ b/toolranks/depends.txt @@ -1,2 +1 @@ default -moreores? diff --git a/toolranks/init.lua b/toolranks/init.lua index 49488a1..e44aea8 100644 --- a/toolranks/init.lua +++ b/toolranks/init.lua @@ -1,4 +1,5 @@ local mod_storage = minetest.get_mod_storage() +local S = minetest.get_translator("toolranks") toolranks = {} @@ -9,270 +10,178 @@ toolranks.colors = { white = minetest.get_color_escape_sequence("#ffffff") } +local max_speed = tonumber(minetest.settings:get("toolranks_speed_multiplier")) or 2.0 +local max_use = tonumber(minetest.settings:get("toolranks_use_multiplier")) or 2.0 +local max_level = tonumber(minetest.settings:get("toolranks_levels")) or 10 +local level_digs = tonumber(minetest.settings:get("toolranks_level_digs")) or 500 +local level_multiplier = 1 / max_level + function toolranks.get_tool_type(description) - if string.find(description, "Pickaxe") then - return "pickaxe" - elseif string.find(description, "Axe") then - return "axe" - elseif string.find(description, "Shovel") then - return "shovel" - elseif string.find(description, "Hoe") then - return "hoe" - else + if not description then return "tool" + else + local d = string.lower(description) + if string.find(d, "pickaxe") then + return "pickaxe" + elseif string.find(d, "axe") then + return "axe" + elseif string.find(d, "shovel") then + return "shovel" + elseif string.find(d, "hoe") then + return "hoe" + elseif string.find(d, "sword") then + return "sword" + else + return "tool" + end end end -function toolranks.create_description(name, uses, level) - local description = name - local tooltype = toolranks.get_tool_type(description) - - local newdesc = toolranks.colors.green .. description .. "\n" .. - toolranks.colors.gold .. "Level " .. (level or 1) .. " " .. tooltype .. "\n" .. - toolranks.colors.grey .. "Nodes dug: " .. (uses or 0) - - return newdesc -end - function toolranks.get_level(uses) - if uses <= 200 then - return 1 - elseif uses < 400 then - return 2 - elseif uses < 1000 then - return 3 - elseif uses < 2000 then - return 4 - elseif uses < 3200 then - return 5 - else - return 6 + if type(uses) == "number" and uses > 0 then + return math.min(max_level, math.floor(uses / level_digs)) end + return 0 +end + +function toolranks.create_description(name, uses) + local description = name + local tooltype = toolranks.get_tool_type(description) + local newdesc = S( + "@1@2\n@3Level @4 @5\n@6@Node dug: @7", + toolranks.colors.green, + description, + toolranks.colors.gold, + toolranks.get_level(uses), + S(tooltype), + toolranks.colors.grey, + (type(uses) == "number" and uses or 0) + ) + return newdesc end function toolranks.new_afteruse(itemstack, user, node, digparams) - local itemmeta = itemstack:get_meta() -- Metadata - local itemdef = itemstack:get_definition() -- Item Definition - local itemdesc = itemdef.original_description -- Original Description - local dugnodes = tonumber(itemmeta:get_string("dug")) or 0 -- Number of nodes dug - local lastlevel = tonumber(itemmeta:get_string("lastlevel")) or 1 -- Level the tool had - -- on the last dig + local itemmeta = itemstack:get_meta() + local itemdef = itemstack:get_definition() + local itemdesc = itemdef.original_description or "" + local dugnodes = tonumber(itemmeta:get_string("dug")) or 0 + local lastlevel = tonumber(itemmeta:get_string("lastlevel")) or 0 local most_digs = mod_storage:get_int("most_digs") or 0 local most_digs_user = mod_storage:get_string("most_digs_user") or 0 - - -- Only count nodes that spend the tool - if(digparams.wear > 0) then - dugnodes = dugnodes + 1 - itemmeta:set_string("dug", dugnodes) + local pname = user:get_player_name() + if not pname then return itemstack end -- player nil check + + if digparams.wear > 0 then -- Only count nodes that spend the tool + dugnodes = dugnodes + 1 + itemmeta:set_string("dug", dugnodes) end - if(dugnodes > most_digs) then - most_digs = dugnodes - if(most_digs_user ~= user:get_player_name()) then -- Avoid spam. - most_digs_user = user:get_player_name() - minetest.chat_send_all("Most used tool is now a " .. toolranks.colors.green .. itemdesc - .. toolranks.colors.white .. " owned by " .. user:get_player_name() - .. " with " .. dugnodes .. " uses.") + + if dugnodes > most_digs then + if most_digs_user ~= pname then -- Avoid spam. + minetest.chat_send_all(S( + "Most used tool is now a @1@2@3 owned by @4 with @5 uses.", + toolranks.colors.green, + itemdesc, + toolranks.colors.white, + pname, + dugnodes + )) end mod_storage:set_int("most_digs", dugnodes) - mod_storage:set_string("most_digs_user", user:get_player_name()) + mod_storage:set_string("most_digs_user", pname) end - if(itemstack:get_wear() > 60135) then - minetest.chat_send_player(user:get_player_name(), "Your tool is about to break!") + + if itemstack:get_wear() > 60135 then + minetest.chat_send_player(user:get_player_name(), S("Your tool is about to break!")) minetest.sound_play("default_tool_breaks", { - to_player = user:get_player_name(), + to_player = pname, gain = 2.0, }) end + local level = toolranks.get_level(dugnodes) - if lastlevel < level then - local levelup_text = "Your " .. toolranks.colors.green .. - itemdesc .. toolranks.colors.white .. - " just leveled up!" + local levelup_text = S( + "Your @1@2@3 just leveled up!", + toolranks.colors.green, + itemdesc, + toolranks.colors.white + ) + minetest.chat_send_player(user:get_player_name(), levelup_text) minetest.sound_play("toolranks_levelup", { - to_player = user:get_player_name(), + to_player = pname, gain = 2.0, }) - minetest.chat_send_player(user:get_player_name(), levelup_text) - itemmeta:set_string("lastlevel", level) + -- Make tool better by modifying tool_capabilities (if defined) + if itemdef.tool_capabilities then + local speed_multiplier = 1 + (level * level_multiplier * (max_speed - 1)) + local use_multiplier = 1 + (level * level_multiplier * (max_use - 1)) + local caps = table.copy(itemdef.tool_capabilities) + + caps.full_punch_interval = caps.full_punch_interval and (caps.full_punch_interval / speed_multiplier) + caps.punch_attack_uses = caps.punch_attack_uses and (caps.punch_attack_uses * use_multiplier) + + for _,c in pairs(caps.groupcaps) do + c.uses = c.uses * use_multiplier + for i,t in ipairs(c.times) do + c.times[i] = t / speed_multiplier + end + end + itemmeta:set_tool_capabilities(caps) + end end - local newdesc = toolranks.create_description(itemdesc, dugnodes, level) - - itemmeta:set_string("description", newdesc) + -- Old method for compatibility with tools without tool_capabilities defined local wear = digparams.wear - if level > 1 then - wear = digparams.wear / (1 + level / 4) + if level > 0 and not itemdef.tool_capabilities then + local use_multiplier = 1 + (level * level_multiplier * (max_use - 1)) + wear = wear / use_multiplier end - --minetest.chat_send_all("wear="..wear.."Original wear: "..digparams.wear.." 1+level/4="..1+level/4) - -- Uncomment for testing ^ - + itemmeta:set_string("lastlevel", level) + itemmeta:set_string("description", toolranks.create_description(itemdesc, dugnodes)) itemstack:add_wear(wear) - return itemstack end -minetest.override_item("default:pick_diamond", { - original_description = "Diamond Pickaxe", - description = toolranks.create_description("Diamond Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_diamond", { - original_description = "Diamond Axe", - description = toolranks.create_description("Diamond Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_diamond", { - original_description = "Diamond Shovel", - description = toolranks.create_description("Diamond Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:pick_wood", { - original_description = "Wooden Pickaxe", - description = toolranks.create_description("Wooden Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_wood", { - original_description = "Wooden Axe", - description = toolranks.create_description("Wooden Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_wood", { - original_description = "Wooden Shovel", - description = toolranks.create_description("Wooden Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:pick_steel", { - original_description = "Steel Pickaxe", - description = toolranks.create_description("Steel Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_steel", { - original_description = "Steel Axe", - description = toolranks.create_description("Steel Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_steel", { - original_description = "Steel Shovel", - description = toolranks.create_description("Steel Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:pick_stone", { - original_description = "Stone Pickaxe", - description = toolranks.create_description("Stone Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_stone", { - original_description = "Stone Axe", - description = toolranks.create_description("Stone Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_stone", { - original_description = "Stone Shovel", - description = toolranks.create_description("Stone Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:pick_bronze", { - original_description = "Bronze Pickaxe", - description = toolranks.create_description("Bronze Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_bronze", { - original_description = "Bronze Axe", - description = toolranks.create_description("Bronze Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_bronze", { - original_description = "Bronze Shovel", - description = toolranks.create_description("Bronze Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:pick_mese", { - original_description = "Mese Pickaxe", - description = toolranks.create_description("Mese Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:axe_mese", { - original_description = "Mese Axe", - description = toolranks.create_description("Mese Axe", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:shovel_mese", { - original_description = "Mese Shovel", - description = toolranks.create_description("Mese Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - -if minetest.get_modpath("moreores") then - - minetest.override_item("moreores:pick_mithril", { - original_description = "Mithril Pickaxe", - description = toolranks.create_description("Mithril Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:axe_mithril", { - original_description = "Mithril Axe", - description = toolranks.create_description("Mithril Axe", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:shovel_mithril", { - original_description = "Mithril Shovel", - description = toolranks.create_description("Mithril Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:sword_mithril", { - original_description = "Mithril Sword", - description = toolranks.create_description("Mithril Sword", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:pick_silver", { - original_description = "Silver Pickaxe", - description = toolranks.create_description("Silver Pickaxe", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:axe_silver", { - original_description = "Silver Axe", - description = toolranks.create_description("Silver Axe", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:shovel_silver", { - original_description = "Silver Shovel", - description = toolranks.create_description("Silver Shovel", 0, 1), - after_use = toolranks.new_afteruse}) - - minetest.override_item("moreores:sword_silver", { - original_description = "Silver Sword", - description = toolranks.create_description("Silver Sword", 0, 1), - after_use = toolranks.new_afteruse}) +-- Helper function +function toolranks.add_tool(name) + local desc = ItemStack(name):get_definition().description + minetest.override_item(name, { + original_description = desc, + description = toolranks.create_description(desc), + after_use = toolranks.new_afteruse + }) end --- add swords for snappy nodes -minetest.override_item("default:sword_wood", { - original_description = "Wooden Sword", - description = toolranks.create_description("Wooden Sword", 0, 1), - after_use = toolranks.new_afteruse}) +-- Sword +toolranks.add_tool("default:sword_wood") +toolranks.add_tool("default:sword_stone") +toolranks.add_tool("default:sword_steel") +toolranks.add_tool("default:sword_bronze") +toolranks.add_tool("default:sword_mese") +toolranks.add_tool("default:sword_diamond") -minetest.override_item("default:sword_stone", { - original_description = "Stone Sword", - description = toolranks.create_description("Stone Sword", 0, 1), - after_use = toolranks.new_afteruse}) +-- Pickaxe +toolranks.add_tool("default:pick_wood") +toolranks.add_tool("default:pick_stone") +toolranks.add_tool("default:pick_steel") +toolranks.add_tool("default:pick_bronze") +toolranks.add_tool("default:pick_mese") +toolranks.add_tool("default:pick_diamond") -minetest.override_item("default:sword_steel", { - original_description = "Steel Sword", - description = toolranks.create_description("Steel Sword", 0, 1), - after_use = toolranks.new_afteruse}) +-- Axe +toolranks.add_tool("default:axe_wood") +toolranks.add_tool("default:axe_stone") +toolranks.add_tool("default:axe_steel") +toolranks.add_tool("default:axe_bronze") +toolranks.add_tool("default:axe_mese") +toolranks.add_tool("default:axe_diamond") -minetest.override_item("default:sword_bronze", { - original_description = "Bronze Sword", - description = toolranks.create_description("Bronze Sword", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:sword_mese", { - original_description = "Mese Sword", - description = toolranks.create_description("Mese Sword", 0, 1), - after_use = toolranks.new_afteruse}) - -minetest.override_item("default:sword_diamond", { - original_description = "Diamond Sword", - description = toolranks.create_description("Diamond Sword", 0, 1), - after_use = toolranks.new_afteruse}) +-- Shovel +toolranks.add_tool("default:shovel_wood") +toolranks.add_tool("default:shovel_stone") +toolranks.add_tool("default:shovel_steel") +toolranks.add_tool("default:shovel_bronze") +toolranks.add_tool("default:shovel_mese") +toolranks.add_tool("default:shovel_diamond") diff --git a/toolranks/locale/toolranks.en.tr b/toolranks/locale/toolranks.en.tr new file mode 100644 index 0000000..9e6b7d8 --- /dev/null +++ b/toolranks/locale/toolranks.en.tr @@ -0,0 +1,11 @@ +# textdomain: toolranks +@1@2@n@3Level @4 @5@n@6Node dug: @7=@1@2@n@3Level @4 @5@n@6Node dug: @7 +pickaxe=pickaxe +axe=axe +shovel=shovel +hoe=hoe +sword=sword +tool=tool +Most used tool is now a @1@2@3 owned by @4 with @5 uses.=Most used tool is now a @1@2@3 owned by @4 with @5 uses. +Your tool is about to break!=Your tool is about to break! +Your @1@2@3 just leveled up!=Your @1@2@3 just leveled up! diff --git a/toolranks/locale/toolranks.fr.tr b/toolranks/locale/toolranks.fr.tr new file mode 100644 index 0000000..2fbefcd --- /dev/null +++ b/toolranks/locale/toolranks.fr.tr @@ -0,0 +1,11 @@ +# textdomain: toolranks +@1@2@n@3Level @4 @5@n@6Node dug: @7=@1@2@n@3@5 niveau @4@n@6Blocks minés : @7 +pickaxe=pioche +axe=hache +shovel=pelle +hoe=houe +sword=épée +tool=outil +Most used tool is now a @1@2@3 owned by @4 with @5 uses.=L’outil le plus utilisé est désormais @1@2@3 appartenant à @4 avec @5 utilisations. +Your tool is about to break!=Votre outil va se casser ! +Your @1@2@3 just leveled up!=Votre @1@2@3 a gagné un niveau ! diff --git a/toolranks/mod.conf b/toolranks/mod.conf new file mode 100644 index 0000000..9b53588 --- /dev/null +++ b/toolranks/mod.conf @@ -0,0 +1,2 @@ +name = toolranks +depends = default diff --git a/toolranks/settingtypes.txt b/toolranks/settingtypes.txt new file mode 100644 index 0000000..5535a20 --- /dev/null +++ b/toolranks/settingtypes.txt @@ -0,0 +1,8 @@ +# Number of tool levels +toolranks_levels (Levels) int 10 +# Number of nodes that need to be dug to reach the next tool level +toolranks_level_digs (Digs per level) int 500 +# Dig speed multiplier at maximum tool level (1.0 to disable) +toolranks_speed_multiplier (Dig speed multiplier) float 2.0 1.0 10.0 +# Durability multiplier at maximum tool level (1.0 to disable) +toolranks_use_multiplier (Durability multiplier) float 2.0 1.0 10.0