123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383 |
- -- Localize for performance.
- local math_floor = math.floor
- if not minetest.global_exists("toolranks") then toolranks = {} end
- toolranks.modpath = minetest.get_modpath("toolranks")
- toolranks.players = toolranks.players or {}
- toolranks.tools = toolranks.tools or {}
- local players = toolranks.players
- if not toolranks.mod_storage then
- toolranks.mod_storage = minetest.get_mod_storage()
- end
- local mod_storage = toolranks.mod_storage
- toolranks.colors = {
- grey = minetest.get_color_escape_sequence("#9d9d9d"),
- green = minetest.get_color_escape_sequence("#1eff00"),
- gold = minetest.get_color_escape_sequence("#ffdf00"),
- white = minetest.get_color_escape_sequence("#ffffff")
- }
- 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"
- elseif string.find(description, "Sword") then
- return "sword"
- else
- return "tool"
- end
- end
- -- Used to apply multiple descriptions into a single description.
- -- Any mod wanting to change a tool's description meta should go through this.
- function toolranks.apply_description(itemmeta, def)
- local desc1 = itemmeta:get_string("en_desc") or ""
- local desc2 = itemmeta:get_string("tr_desc") or ""
- local desc3 = itemmeta:get_string("ar_desc") or ""
- if desc1 == "" then
- -- No custom description set by engraver, etc.?
- -- Use original description.
- desc1 = def.original_description or ""
- if desc1 == "" then
- desc1 = def.description or ""
- end
- end
- if desc2 == "" then
- -- Nothing assigned by TR yet? Use default TR desc, if any.
- desc2 = def.original_tr_description or ""
- end
- if desc3 ~= "" then
- desc3 = "Loaded: " .. desc3
- end
- if desc2 ~= "" then
- -- Have toolranks description? Seperate with newlines.
- desc1 = desc1 .. "\n\n"
- end
- if desc3 ~= "" then
- desc2 = desc2 .. "\n\n"
- end
- itemmeta:set_string("description", desc1 .. desc2 .. desc3)
- end
- function toolranks.create_description(name, uses, level)
- local description = utility.get_short_desc(name)
- local tooltype = toolranks.get_tool_type(description)
- local strpart = "Nodes dug"
- if tooltype == "sword" then
- strpart = "Blows struck"
- elseif tooltype == "pickaxe" then
- strpart = "Resources picked"
- elseif tooltype == "axe" then
- strpart = "Resources chopped"
- elseif tooltype == "shovel" then
- strpart = "Resources shoveled"
- end
- local newdesc = toolranks.colors.green .. description .. "\n" ..
- toolranks.colors.gold .. "Level " .. (level or 1) .. " " .. tooltype .. "\n" ..
- toolranks.colors.grey .. strpart .. ": " .. (uses or 0)
- return newdesc
- end
- function toolranks.get_level(uses, max_uses, old_level)
- -- Uncomment this to enable rapidly testing the tool-rank leveling function.
- --max_uses = 5
- local lvl = 1
- -- subtract 1 from max_uses so that the tool levels up right before it is broken
- if uses <= max_uses-1 then
- lvl = 1
- elseif uses < max_uses*2-1 then
- lvl = 2
- elseif uses < max_uses*3-1 then
- lvl = 3
- elseif uses < max_uses*4-1 then
- lvl = 4
- elseif uses < max_uses*5-1 then
- lvl = 5
- elseif uses < max_uses*7-1 then -- level 7 requires twice the number of nodes dug as previous levels
- lvl = 6
- else
- lvl = 7 -- at level 7, tool wear is cut in half
- end
- if lvl < old_level then
- lvl = old_level
- end
- return lvl
- end
- -- API function: allow to get the rank-level of a tool,
- -- (or 0, if the item is not a tool).
- -- The lowest possible (valid) rank is 1.
- function toolranks.get_tool_level(item)
- local name = item:get_name()
- local count = item:get_count()
- if count == 1 and toolranks.tools[name] then
- local meta = item:get_meta()
- local rank = tonumber(meta:get_string("tr_lastlevel")) or 1
- return rank
- end
- return 0
- end
- function toolranks.new_afteruse(itemstack, user, node, digparams)
- -- If either is not specified, then behave like builtin.
- if not user or not node then
- itemstack:add_wear(digparams.wear)
- return itemstack
- end
- local pname = user:get_player_name()
- -- Initialize data if not already done.
- local pdata = players[pname]
- if not pdata then
- players[pname] = {}
- pdata = players[pname]
- -- Default values.
- pdata.last_node = node.name -- Name of the last node dug, used for caching.
- pdata.last_ignore = false
- local ndef = minetest.registered_nodes[node.name]
- if ndef then
- if ndef._toolranks then
- if ndef._toolranks.ignore then
- pdata.last_ignore = true
- end
- end
- else
- -- Ignore unknown nodes.
- pdata.last_ignore = true
- end
- end
- -- Get cached player data.
- if pdata.last_node ~= node.name then
- pdata.last_node = node.name
- pdata.last_ignore = false
- -- If this node is different from the last node, update cached information.
- local ndef = minetest.registered_nodes[node.name]
- if ndef then
- if ndef._toolranks then
- if ndef._toolranks.ignore then
- pdata.last_ignore = true
- end
- end
- else
- -- Ignore unknown nodes.
- pdata.last_ignore = true
- end
- end
- local ignore_this_node = pdata.last_ignore
- 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("tr_dug")) or 0 -- Number of nodes dug
- local lastlevel = tonumber(itemmeta:get_string("tr_lastlevel")) or 1 -- Level the tool had
- -- Only count nodes that spend the tool
- if not ignore_this_node then
- if(digparams.wear > 0) then
- dugnodes = dugnodes + 1
- itemmeta:set_string("tr_dug", dugnodes)
- end
- end
- -- Don't print message more than once every 5 seconds.
- local os_time = os.time()
- if os_time > (pdata.last_alert or 0) + 5 then
- if(itemstack:get_wear() > 60135) then
- minetest.chat_send_player(pname, "# Server: Your tool is about to break!")
- ambiance.sound_play("default_tool_breaks", user:get_pos(), 1.0, 20)
- pdata.last_alert = os_time
- end
- end
- -- pass total number of nodes (of this type) that could be dug assuming no tool repairs, as second param to this function
- local level = toolranks.get_level(dugnodes, math_floor(65535 / digparams.wear), lastlevel)
- -- New level should never be less than the old level.
- if lastlevel < level then
- local levelup_text = "# Server: Your " .. utility.get_short_desc(itemdesc) .. " just leveled up!"
- ambiance.sound_play("toolranks_levelup", user:get_pos(), 1.0, 20)
- minetest.chat_send_player(pname, levelup_text)
- itemmeta:set_string("tr_lastlevel", level)
- end
- local newdesc = toolranks.create_description(itemdesc, dugnodes, level)
- itemmeta:set_string("tr_desc", newdesc)
- toolranks.apply_description(itemmeta, itemdef)
- local wear = digparams.wear
- if level > 1 then
- wear = digparams.wear / (1 + level / 4)
- end
- --minetest.chat_send_all("wear="..wear.."Original wear: "..digparams.wear.." 1+level/4="..1+level/4)
- -- Uncomment for testing ^
- itemstack:add_wear(wear)
- return itemstack
- end
- -- This code was used at one time to replace a valuable tool someone had lost
- -- due to a bug.
- --[[
- function toolranks.rebuild_tool()
- local player = minetest.get_player_by_name("MustTest")
- local inv = player:get_inventory()
- local item = inv:get_stack("main", 1)
- local meta = item:get_meta()
- meta:set_string("tr_dug", "58194")
- meta:set_string("tr_lastlevel", "7")
- meta:set_string("en_desc", "Trusted")
- local newdesc = toolranks.create_description(item:get_definition().original_description, 58194, 7)
- meta:set_string("tr_desc", newdesc)
- toolranks.apply_description(meta, item:get_definition())
- inv:set_stack("main", 1, item)
- end
- --]]
- if not toolranks.registered then
- local function override_item(name)
- --print(name)
- toolranks.tools[name] = true
- local itemdef = table.copy(minetest.registered_items[name])
- -- Found out by reading MT sources that these must both be nill'ed.
- -- Otherwise we get error: Attempt to redefine name of X to "X".
- itemdef.name = nil
- itemdef.type = nil
- local tr_desc = toolranks.create_description(itemdef.description, 0, 1)
- itemdef.original_description = itemdef.description
- itemdef.description = itemdef.description .. "\n\n" .. tr_desc
- itemdef.original_tr_description = tr_desc
- itemdef.after_use = function(...) return toolranks.new_afteruse(...) end
- minetest.override_item(name, itemdef)
- end
- override_item("default:pick_diamond")
- override_item("default:axe_diamond")
- override_item("default:shovel_diamond")
- override_item("default:pick_wood")
- --override_item("default:axe_wood")
- --override_item("default:shovel_wood")
- override_item("default:pick_steel")
- override_item("default:axe_steel")
- override_item("default:shovel_steel")
- override_item("default:pick_stone")
- override_item("default:axe_stone")
- override_item("default:shovel_stone")
- override_item("default:pick_bronze")
- override_item("default:axe_bronze")
- override_item("default:shovel_bronze")
- override_item("default:pick_bronze2")
- override_item("default:axe_bronze2")
- override_item("default:shovel_bronze2")
- override_item("default:pick_mese")
- override_item("default:axe_mese")
- override_item("default:shovel_mese")
- if minetest.get_modpath("moreores") then
- override_item("moreores:pick_mithril")
- override_item("moreores:axe_mithril")
- override_item("moreores:shovel_mithril")
- override_item("moreores:sword_mithril")
- override_item("moreores:pick_silver")
- override_item("moreores:axe_silver")
- override_item("moreores:shovel_silver")
- override_item("moreores:sword_silver")
- end
- -- add swords for snappy nodes
- --override_item("default:sword_wood")
- override_item("default:sword_stone")
- override_item("default:sword_steel")
- override_item("default:sword_bronze")
- override_item("default:sword_bronze2")
- override_item("default:sword_mese")
- override_item("default:sword_diamond")
- if minetest.get_modpath("titanium") then
- override_item("titanium:sword")
- override_item("titanium:axe")
- override_item("titanium:shovel")
- override_item("titanium:pick")
- end
- if minetest.get_modpath("gem_tools") then
- override_item("gems:sword_emerald")
- override_item("gems:axe_emerald")
- override_item("gems:shovel_emerald")
- override_item("gems:pick_emerald")
- override_item("gems:sword_ruby")
- override_item("gems:axe_ruby")
- override_item("gems:shovel_ruby")
- override_item("gems:pick_ruby")
- override_item("gems:sword_amethyst")
- override_item("gems:axe_amethyst")
- override_item("gems:shovel_amethyst")
- override_item("gems:pick_amethyst")
- override_item("gems:sword_sapphire")
- override_item("gems:axe_sapphire")
- override_item("gems:shovel_sapphire")
- override_item("gems:pick_sapphire")
- override_item("gems:rf_sword_emerald")
- override_item("gems:rf_axe_emerald")
- override_item("gems:rf_shovel_emerald")
- override_item("gems:rf_pick_emerald")
- override_item("gems:rf_sword_ruby")
- override_item("gems:rf_axe_ruby")
- override_item("gems:rf_shovel_ruby")
- override_item("gems:rf_pick_ruby")
- override_item("gems:rf_sword_amethyst")
- override_item("gems:rf_axe_amethyst")
- override_item("gems:rf_shovel_amethyst")
- override_item("gems:rf_pick_amethyst")
- override_item("gems:rf_sword_sapphire")
- override_item("gems:rf_axe_sapphire")
- override_item("gems:rf_shovel_sapphire")
- override_item("gems:rf_pick_sapphire")
- end
- local c = "toolranks:core"
- local f = toolranks.modpath .. "/init.lua"
- reload.register_file(c, f, false)
- toolranks.registered = true
- end
|