init.lua 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346
  1. toolranks = toolranks or {}
  2. toolranks.modpath = minetest.get_modpath("toolranks")
  3. toolranks.players = toolranks.players or {}
  4. local players = toolranks.players
  5. if not toolranks.mod_storage then
  6. toolranks.mod_storage = minetest.get_mod_storage()
  7. end
  8. local mod_storage = toolranks.mod_storage
  9. toolranks.colors = {
  10. grey = minetest.get_color_escape_sequence("#9d9d9d"),
  11. green = minetest.get_color_escape_sequence("#1eff00"),
  12. gold = minetest.get_color_escape_sequence("#ffdf00"),
  13. white = minetest.get_color_escape_sequence("#ffffff")
  14. }
  15. function toolranks.get_tool_type(description)
  16. if string.find(description, "Pickaxe") then
  17. return "pickaxe"
  18. elseif string.find(description, "Axe") then
  19. return "axe"
  20. elseif string.find(description, "Shovel") then
  21. return "shovel"
  22. elseif string.find(description, "Hoe") then
  23. return "hoe"
  24. elseif string.find(description, "Sword") then
  25. return "sword"
  26. else
  27. return "tool"
  28. end
  29. end
  30. -- Used to apply multiple descriptions into a single description.
  31. -- Any mod wanting to change a tool's description meta should go through this.
  32. function toolranks.apply_description(itemmeta, def)
  33. local desc1 = itemmeta:get_string("en_desc") or ""
  34. local desc2 = itemmeta:get_string("tr_desc") or ""
  35. local desc3 = itemmeta:get_string("ar_desc") or ""
  36. if desc1 == "" then
  37. -- No custom description set by engraver, etc.?
  38. -- Use original description.
  39. desc1 = def.original_description or ""
  40. if desc1 == "" then
  41. desc1 = def.description or ""
  42. end
  43. end
  44. if desc2 == "" then
  45. -- Nothing assigned by TR yet? Use default TR desc, if any.
  46. desc2 = def.original_tr_description or ""
  47. end
  48. if desc3 ~= "" then
  49. desc3 = "Loaded: " .. desc3
  50. end
  51. if desc2 ~= "" then
  52. -- Have toolranks description? Seperate with newlines.
  53. desc1 = desc1 .. "\n\n"
  54. end
  55. if desc3 ~= "" then
  56. desc2 = desc2 .. "\n\n"
  57. end
  58. itemmeta:set_string("description", desc1 .. desc2 .. desc3)
  59. end
  60. function toolranks.create_description(name, uses, level)
  61. local description = utility.get_short_desc(name)
  62. local tooltype = toolranks.get_tool_type(description)
  63. local strpart = "Nodes dug"
  64. if tooltype == "sword" then
  65. strpart = "Weapon strikes"
  66. elseif tooltype == "pickaxe" then
  67. strpart = "Nodes picked"
  68. elseif tooltype == "axe" then
  69. strpart = "Nodes chopped"
  70. elseif tooltype == "shovel" then
  71. strpart = "Nodes shoveled"
  72. end
  73. local newdesc = toolranks.colors.green .. description .. "\n" ..
  74. toolranks.colors.gold .. "Level " .. (level or 1) .. " " .. tooltype .. "\n" ..
  75. toolranks.colors.grey .. strpart .. ": " .. (uses or 0)
  76. return newdesc
  77. end
  78. function toolranks.get_level(uses, max_uses, old_level)
  79. local lvl = 1
  80. -- subtract 1 from max_uses so that the tool levels up right before it is broken
  81. if uses <= max_uses-1 then
  82. lvl = 1
  83. elseif uses < max_uses*2-1 then
  84. lvl = 2
  85. elseif uses < max_uses*3-1 then
  86. lvl = 3
  87. elseif uses < max_uses*4-1 then
  88. lvl = 4
  89. elseif uses < max_uses*5-1 then
  90. lvl = 5
  91. elseif uses < max_uses*7-1 then -- level 7 requires twice the number of nodes dug as previous levels
  92. lvl = 6
  93. else
  94. lvl = 7 -- at level 7, tool wear is cut in half
  95. end
  96. if lvl < old_level then
  97. lvl = old_level
  98. end
  99. return lvl
  100. end
  101. function toolranks.new_afteruse(itemstack, user, node, digparams)
  102. -- If either is not specified, then behave like builtin.
  103. if not user or not node then
  104. itemstack:add_wear(digparams.wear)
  105. return itemstack
  106. end
  107. local pname = user:get_player_name()
  108. -- Initialize data if not already done.
  109. local pdata = players[pname]
  110. if not pdata then
  111. players[pname] = {}
  112. pdata = players[pname]
  113. -- Default values.
  114. pdata.last_node = node.name -- Name of the last node dug, used for caching.
  115. pdata.last_ignore = false
  116. local ndef = minetest.registered_nodes[node.name]
  117. if ndef then
  118. if ndef._toolranks then
  119. if ndef._toolranks.ignore then
  120. pdata.last_ignore = true
  121. end
  122. end
  123. else
  124. -- Ignore unknown nodes.
  125. pdata.last_ignore = true
  126. end
  127. end
  128. -- Get cached player data.
  129. if pdata.last_node ~= node.name then
  130. pdata.last_node = node.name
  131. pdata.last_ignore = false
  132. -- If this node is different from the last node, update cached information.
  133. local ndef = minetest.registered_nodes[node.name]
  134. if ndef then
  135. if ndef._toolranks then
  136. if ndef._toolranks.ignore then
  137. pdata.last_ignore = true
  138. end
  139. end
  140. else
  141. -- Ignore unknown nodes.
  142. pdata.last_ignore = true
  143. end
  144. end
  145. local ignore_this_node = pdata.last_ignore
  146. local itemmeta = itemstack:get_meta() -- Metadata
  147. local itemdef = itemstack:get_definition() -- Item Definition
  148. local itemdesc = itemdef.original_description -- Original Description
  149. local dugnodes = tonumber(itemmeta:get_string("tr_dug")) or 0 -- Number of nodes dug
  150. local lastlevel = tonumber(itemmeta:get_string("tr_lastlevel")) or 1 -- Level the tool had
  151. -- Only count nodes that spend the tool
  152. if not ignore_this_node then
  153. if(digparams.wear > 0) then
  154. dugnodes = dugnodes + 1
  155. itemmeta:set_string("tr_dug", dugnodes)
  156. end
  157. end
  158. -- Don't print message more than once every 5 seconds.
  159. local os_time = os.time()
  160. if os_time > (pdata.last_alert or 0) + 5 then
  161. if(itemstack:get_wear() > 60135) then
  162. minetest.chat_send_player(pname, "# Server: Your tool is about to break!")
  163. ambiance.sound_play("default_tool_breaks", user:get_pos(), 1.0, 20)
  164. pdata.last_alert = os_time
  165. end
  166. end
  167. -- pass total number of nodes (of this type) that could be dug assuming no tool repairs, as second param to this function
  168. local level = toolranks.get_level(dugnodes, math.floor(65535 / digparams.wear), lastlevel)
  169. -- New level should never be less than the old level.
  170. if lastlevel < level then
  171. local levelup_text = "# Server: Your " .. utility.get_short_desc(itemdesc) .. " just leveled up!"
  172. ambiance.sound_play("toolranks_levelup", user:get_pos(), 1.0, 20)
  173. minetest.chat_send_player(pname, levelup_text)
  174. itemmeta:set_string("tr_lastlevel", level)
  175. end
  176. local newdesc = toolranks.create_description(itemdesc, dugnodes, level)
  177. itemmeta:set_string("tr_desc", newdesc)
  178. toolranks.apply_description(itemmeta, itemdef)
  179. local wear = digparams.wear
  180. if level > 1 then
  181. wear = digparams.wear / (1 + level / 4)
  182. end
  183. --minetest.chat_send_all("wear="..wear.."Original wear: "..digparams.wear.." 1+level/4="..1+level/4)
  184. -- Uncomment for testing ^
  185. itemstack:add_wear(wear)
  186. return itemstack
  187. end
  188. function toolranks.rebuild_tool()
  189. local player = minetest.get_player_by_name("MustTest")
  190. local inv = player:get_inventory()
  191. local item = inv:get_stack("main", 1)
  192. local meta = item:get_meta()
  193. meta:set_string("tr_dug", "58194")
  194. meta:set_string("tr_lastlevel", "7")
  195. meta:set_string("en_desc", "Trusted")
  196. local newdesc = toolranks.create_description(item:get_definition().original_description, 58194, 7)
  197. meta:set_string("tr_desc", newdesc)
  198. toolranks.apply_description(meta, item:get_definition())
  199. inv:set_stack("main", 1, item)
  200. end
  201. if not toolranks.registered then
  202. local function override_item(name)
  203. --print(name)
  204. local itemdef = table.copy(minetest.registered_items[name])
  205. -- Found out by reading MT sources that these must both be nill'ed.
  206. -- Otherwise we get error: Attempt to redefine name of X to "X".
  207. itemdef.name = nil
  208. itemdef.type = nil
  209. local tr_desc = toolranks.create_description(itemdef.description, 0, 1)
  210. itemdef.original_description = itemdef.description
  211. itemdef.description = itemdef.description .. "\n\n" .. tr_desc
  212. itemdef.original_tr_description = tr_desc
  213. itemdef.after_use = function(...) return toolranks.new_afteruse(...) end
  214. minetest.override_item(name, itemdef)
  215. end
  216. override_item("default:pick_diamond")
  217. override_item("default:axe_diamond")
  218. override_item("default:shovel_diamond")
  219. override_item("default:pick_wood")
  220. --override_item("default:axe_wood")
  221. --override_item("default:shovel_wood")
  222. override_item("default:pick_steel")
  223. override_item("default:axe_steel")
  224. override_item("default:shovel_steel")
  225. override_item("default:pick_stone")
  226. override_item("default:axe_stone")
  227. override_item("default:shovel_stone")
  228. override_item("default:pick_bronze")
  229. override_item("default:axe_bronze")
  230. override_item("default:shovel_bronze")
  231. override_item("default:pick_mese")
  232. override_item("default:axe_mese")
  233. override_item("default:shovel_mese")
  234. if minetest.get_modpath("moreores") then
  235. override_item("moreores:pick_mithril")
  236. override_item("moreores:axe_mithril")
  237. override_item("moreores:shovel_mithril")
  238. override_item("moreores:sword_mithril")
  239. override_item("moreores:pick_silver")
  240. override_item("moreores:axe_silver")
  241. override_item("moreores:shovel_silver")
  242. override_item("moreores:sword_silver")
  243. end
  244. -- add swords for snappy nodes
  245. --override_item("default:sword_wood")
  246. override_item("default:sword_stone")
  247. override_item("default:sword_steel")
  248. override_item("default:sword_bronze")
  249. override_item("default:sword_mese")
  250. override_item("default:sword_diamond")
  251. if minetest.get_modpath("titanium") then
  252. override_item("titanium:sword")
  253. override_item("titanium:axe")
  254. override_item("titanium:shovel")
  255. override_item("titanium:pick")
  256. end
  257. if minetest.get_modpath("gem_tools") then
  258. override_item("gems:sword_emerald")
  259. override_item("gems:axe_emerald")
  260. override_item("gems:shovel_emerald")
  261. override_item("gems:pick_emerald")
  262. override_item("gems:sword_ruby")
  263. override_item("gems:axe_ruby")
  264. override_item("gems:shovel_ruby")
  265. override_item("gems:pick_ruby")
  266. override_item("gems:sword_amethyst")
  267. override_item("gems:axe_amethyst")
  268. override_item("gems:shovel_amethyst")
  269. override_item("gems:pick_amethyst")
  270. override_item("gems:sword_sapphire")
  271. override_item("gems:axe_sapphire")
  272. override_item("gems:shovel_sapphire")
  273. override_item("gems:pick_sapphire")
  274. override_item("gems:rf_sword_emerald")
  275. override_item("gems:rf_axe_emerald")
  276. override_item("gems:rf_shovel_emerald")
  277. override_item("gems:rf_pick_emerald")
  278. override_item("gems:rf_sword_ruby")
  279. override_item("gems:rf_axe_ruby")
  280. override_item("gems:rf_shovel_ruby")
  281. override_item("gems:rf_pick_ruby")
  282. override_item("gems:rf_sword_amethyst")
  283. override_item("gems:rf_axe_amethyst")
  284. override_item("gems:rf_shovel_amethyst")
  285. override_item("gems:rf_pick_amethyst")
  286. override_item("gems:rf_sword_sapphire")
  287. override_item("gems:rf_axe_sapphire")
  288. override_item("gems:rf_shovel_sapphire")
  289. override_item("gems:rf_pick_sapphire")
  290. end
  291. local c = "toolranks:core"
  292. local f = toolranks.modpath .. "/init.lua"
  293. reload.register_file(c, f, false)
  294. toolranks.registered = true
  295. end