triggers.lua 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536
  1. -- AWARDS
  2. --
  3. -- Copyright (C) 2013-2015 rubenwardy
  4. -- This program is free software; you can redistribute it and/or modify
  5. -- it under the terms of the GNU Lesser General Public License as published by
  6. -- the Free Software Foundation; either version 2.1 of the License, or
  7. -- (at your option) any later version.
  8. -- This program is distributed in the hope that it will be useful,
  9. -- but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. -- GNU Lesser General Public License for more details.
  12. -- You should have received a copy of the GNU Lesser General Public License along
  13. -- with this program; if not, write to the Free Software Foundation, Inc.,
  14. -- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. --
  16. local S, NS = lottachievements.gettext, lottachievements.ngettext
  17. lottachievements.register_trigger("dig", function(def)
  18. local tmp = {
  19. award = def.name,
  20. node = def.trigger.node,
  21. target = def.trigger.target,
  22. }
  23. table.insert(lottachievements.on.dig, tmp)
  24. def.getProgress = function(self, data)
  25. local itemcount
  26. if tmp.node then
  27. itemcount = lottachievements.get_item_count(data, "count", tmp.node) or 0
  28. else
  29. itemcount = lottachievements.get_total_item_count(data, "count")
  30. end
  31. if itemcount > tmp.target then
  32. itemcount = tmp.target
  33. end
  34. return {
  35. perc = itemcount / tmp.target,
  36. label = S("@1/@2 dug", itemcount, tmp.target),
  37. }
  38. end
  39. def.getDefaultDescription = function(self)
  40. local n = self.trigger.target
  41. if self.trigger.node then
  42. local nname = minetest.registered_nodes[self.trigger.node].description
  43. if nname == nil then
  44. nname = self.trigger.node
  45. end
  46. -- Translators: @1 is count, @2 is description.
  47. return NS("Mine: @2", "Mine: @1×@2", n, n, nname)
  48. else
  49. return NS("Mine @1 block.", "Mine @1 blocks.", n, n)
  50. end
  51. end
  52. end)
  53. lottachievements.register_trigger("place", function(def)
  54. local tmp = {
  55. award = def.name,
  56. node = def.trigger.node,
  57. target = def.trigger.target,
  58. }
  59. table.insert(lottachievements.on.place, tmp)
  60. def.getProgress = function(self, data)
  61. local itemcount
  62. if tmp.node then
  63. itemcount = lottachievements.get_item_count(data, "place", tmp.node) or 0
  64. else
  65. itemcount = lottachievements.get_total_item_count(data, "place")
  66. end
  67. if itemcount > tmp.target then
  68. itemcount = tmp.target
  69. end
  70. return {
  71. perc = itemcount / tmp.target,
  72. label = S("@1/@2 placed", itemcount, tmp.target),
  73. }
  74. end
  75. def.getDefaultDescription = function(self)
  76. local n = self.trigger.target
  77. if self.trigger.node then
  78. local nname = minetest.registered_nodes[self.trigger.node].description
  79. if nname == nil then
  80. nname = self.trigger.node
  81. end
  82. -- Translators: @1 is count, @2 is description.
  83. return NS("Place: @2", "Place: @1×@2", n, n, nname)
  84. else
  85. return NS("Place a block.", "Place @1 blocks.", n, n)
  86. end
  87. end
  88. end)
  89. lottachievements.register_trigger("eat", function(def)
  90. local tmp = {
  91. award = def.name,
  92. item = def.trigger.item,
  93. target = def.trigger.target,
  94. }
  95. table.insert(lottachievements.on.eat, tmp)
  96. def.getProgress = function(self, data)
  97. local itemcount
  98. if tmp.item then
  99. itemcount = lottachievements.get_item_count(data, "eat", tmp.item) or 0
  100. else
  101. itemcount = lottachievements.get_total_item_count(data, "eat")
  102. end
  103. if itemcount > tmp.target then
  104. itemcount = tmp.target
  105. end
  106. return {
  107. perc = itemcount / tmp.target,
  108. label = S("@1/@2 eaten", itemcount, tmp.target),
  109. }
  110. end
  111. def.getDefaultDescription = function(self)
  112. local n = self.trigger.target
  113. if self.trigger.item then
  114. local iname = minetest.registered_items[self.trigger.item].description
  115. if iname == nil then
  116. iname = self.trigger.iode
  117. end
  118. -- Translators: @1 is count, @2 is description.
  119. return NS("Eat: @2", "Eat: @1×@2", n, n, iname)
  120. else
  121. return NS("Eat an item.", "Eat @1 items.", n, n)
  122. end
  123. end
  124. end)
  125. lottachievements.register_trigger("death", function(def)
  126. local tmp = {
  127. award = def.name,
  128. target = def.trigger.target,
  129. }
  130. table.insert(lottachievements.on.death, tmp)
  131. def.getProgress = function(self, data)
  132. local itemcount = data.deaths or 0
  133. if itemcount > tmp.target then
  134. itemcount = tmp.target
  135. end
  136. return {
  137. perc = itemcount / tmp.target,
  138. label = S("@1/@2 deaths", itemcount, tmp.target),
  139. }
  140. end
  141. def.getDefaultDescription = function(self)
  142. local n = self.trigger.target
  143. return NS("Die.", "Die @1 times.", n, n)
  144. end
  145. end)
  146. lottachievements.register_trigger("chat", function(def)
  147. local tmp = {
  148. award = def.name,
  149. target = def.trigger.target,
  150. }
  151. table.insert(lottachievements.on.chat, tmp)
  152. def.getProgress = function(self, data)
  153. local itemcount = data.chats or 0
  154. if itemcount > tmp.target then
  155. itemcount = tmp.target
  156. end
  157. return {
  158. perc = itemcount / tmp.target,
  159. label = S("@1/@2 chat messages", itemcount, tmp.target),
  160. }
  161. end
  162. def.getDefaultDescription = function(self)
  163. local n = self.trigger.target
  164. return NS("Write something in chat.", "Write @1 chat messages.", n, n)
  165. end
  166. end)
  167. lottachievements.register_trigger("join", function(def)
  168. local tmp = {
  169. award = def.name,
  170. target = def.trigger.target,
  171. }
  172. table.insert(lottachievements.on.join, tmp)
  173. def.getProgress = function(self, data)
  174. local itemcount = data.joins or 0
  175. if itemcount > tmp.target then
  176. itemcount = tmp.target
  177. end
  178. return {
  179. perc = itemcount / tmp.target,
  180. label = S("@1/@2 game joins", itemcount, tmp.target),
  181. }
  182. end
  183. def.getDefaultDescription = function(self)
  184. local n = self.trigger.target
  185. return NS("Join the game.", "Join the game @1 times.", n, n)
  186. end
  187. end)
  188. lottachievements.register_trigger("craft", function(def)
  189. local tmp = {
  190. award = def.name,
  191. item = def.trigger.item,
  192. target = def.trigger.target,
  193. }
  194. table.insert(lottachievements.on.craft, tmp)
  195. def.getProgress = function(self, data)
  196. local itemcount
  197. if tmp.item then
  198. itemcount = lottachievements.get_item_count(data, "craft", tmp.item) or 0
  199. else
  200. itemcount = lottachievements.get_total_item_count(data, "craft")
  201. end
  202. if itemcount > tmp.target then
  203. itemcount = tmp.target
  204. end
  205. return {
  206. perc = itemcount / tmp.target,
  207. label = S("@1/@2 crafted", itemcount, tmp.target),
  208. }
  209. end
  210. def.getDefaultDescription = function(self)
  211. local n = self.trigger.target
  212. if self.trigger.item then
  213. local iname = minetest.registered_items[self.trigger.item].description
  214. if iname == nil then
  215. iname = self.trigger.item
  216. end
  217. -- Translators: @1 is count, @2 is description.
  218. return NS("Craft: @2", "Craft: @1×@2", n, n, iname)
  219. else
  220. return NS("Craft an item.", "Craft @1 items.", n)
  221. end
  222. end
  223. end)
  224. lottachievements.register_trigger("equip", function(def)
  225. local tmp = {
  226. award = def.name,
  227. item = def.trigger.item,
  228. }
  229. table.insert(lottachievements.on.equip, tmp)
  230. def.getDefaultDescription = function(self)
  231. if self.trigger.item then
  232. local iname = minetest.registered_items[self.trigger.item].description
  233. if iname == nil then
  234. iname = self.trigger.iode
  235. end
  236. -- Translators: @1 is count, @2 is description.
  237. return NS("Eat: @2", "Eat: @1×@2", 4, 4, iname)
  238. else
  239. return NS("Eat an item.", "Eat @1 items.", 4, 4)
  240. end
  241. end
  242. end)
  243. lottachievements.register_trigger("kill", function(def)
  244. local tmp = {
  245. award = def.name,
  246. mob = def.trigger.mob,
  247. target = def.trigger.target,
  248. }
  249. table.insert(lottachievements.on.kill, tmp)
  250. def.getProgress = function(self, data)
  251. local itemcount
  252. if tmp.mob then
  253. itemcount = lottachievements.get_item_count(data, "kill", tmp.mob) or 0
  254. else
  255. itemcount = lottachievements.get_total_item_count(data, "kill")
  256. end
  257. if itemcount > tmp.target then
  258. itemcount = tmp.target
  259. end
  260. return {
  261. perc = itemcount / tmp.target,
  262. label = S("@1/@2 killed", itemcount, tmp.target),
  263. }
  264. end
  265. def.getDefaultDescription = function(self)
  266. local n = self.trigger.target
  267. if self.trigger.mob then
  268. local iname = string.split(self.trigger.mob, ":")[2]
  269. iname = string.gsub(iname, "_", " "):gsub("^%l", string.upper)
  270. if iname == nil then
  271. iname = self.trigger.mob
  272. end
  273. -- Translators: @1 is count, @2 is description.
  274. return NS("Kill: @2", "Kill: @1×@2", n, n, iname)
  275. end
  276. end
  277. end)
  278. -- Backwards compatibility
  279. lottachievements.register_onDig = lottachievements.register_on_dig
  280. lottachievements.register_onPlace = lottachievements.register_on_place
  281. lottachievements.register_onDeath = lottachievements.register_on_death
  282. lottachievements.register_onChat = lottachievements.register_on_chat
  283. lottachievements.register_onJoin = lottachievements.register_on_join
  284. lottachievements.register_onCraft = lottachievements.register_on_craft
  285. -- Trigger Handles
  286. minetest.register_on_dignode(function(pos, oldnode, digger)
  287. if not digger or not pos or not oldnode then
  288. return
  289. end
  290. local data = lottachievements.players[digger:get_player_name()]
  291. if not lottachievements.increment_item_counter(data, "count", oldnode.name) then
  292. return
  293. end
  294. lottachievements.run_trigger_callbacks(digger, data, "dig", function(entry)
  295. if entry.target then
  296. if entry.node then
  297. local tnodedug = string.split(entry.node, ":")
  298. local tmod = tnodedug[1]
  299. local titem = tnodedug[2]
  300. if not tmod or not titem or not data.count[tmod] or not data.count[tmod][titem] then
  301. -- table running failed!
  302. elseif data.count[tmod][titem] > entry.target-1 then
  303. return entry.award
  304. end
  305. elseif lottachievements.get_total_item_count(data, "count") > entry.target-1 then
  306. return entry.award
  307. end
  308. end
  309. end)
  310. end)
  311. minetest.register_on_placenode(function(pos, node, digger)
  312. if not digger or not pos or not node or not digger:get_player_name() or digger:get_player_name()=="" then
  313. return
  314. end
  315. local data = lottachievements.players[digger:get_player_name()]
  316. if not lottachievements.increment_item_counter(data, "place", node.name) then
  317. return
  318. end
  319. lottachievements.run_trigger_callbacks(digger, data, "place", function(entry)
  320. if entry.target then
  321. if entry.node then
  322. local tnodedug = string.split(entry.node, ":")
  323. local tmod = tnodedug[1]
  324. local titem = tnodedug[2]
  325. if not tmod or not titem or not data.place[tmod] or not data.place[tmod][titem] then
  326. -- table running failed!
  327. elseif data.place[tmod][titem] > entry.target-1 then
  328. return entry.award
  329. end
  330. elseif lottachievements.get_total_item_count(data, "place") > entry.target-1 then
  331. return entry.award
  332. end
  333. end
  334. end)
  335. end)
  336. minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack,
  337. user, pointed_thing, old_itemstack, old_level, level)
  338. if not user or not itemstack or not user:get_player_name()
  339. or user:get_player_name() == "" or level == old_level then
  340. return
  341. end
  342. local data = lottachievements.players[user:get_player_name()]
  343. if not lottachievements.increment_item_counter(data, "eat", itemstack:get_name()) then
  344. return
  345. end
  346. lottachievements.run_trigger_callbacks(user, data, "eat", function(entry)
  347. if entry.target then
  348. if entry.item then
  349. local titemstring = string.split(entry.item, ":")
  350. local tmod = titemstring[1]
  351. local titem = titemstring[2]
  352. if not tmod or not titem or not data.eat[tmod] or not data.eat[tmod][titem] then
  353. -- table running failed!
  354. elseif data.eat[tmod][titem] > entry.target-1 then
  355. return entry.award
  356. end
  357. elseif lottachievements.get_total_item_count(data, "eat") > entry.target-1 then
  358. return entry.award
  359. end
  360. end
  361. end)
  362. end)
  363. minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
  364. if not player or not itemstack then
  365. return
  366. end
  367. local data = lottachievements.players[player:get_player_name()]
  368. if not lottachievements.increment_item_counter(data, "craft", itemstack:get_name(), itemstack:get_count()) then
  369. return
  370. end
  371. lottachievements.run_trigger_callbacks(player, data, "craft", function(entry)
  372. if entry.target then
  373. if entry.item then
  374. local titemcrafted = string.split(entry.item, ":")
  375. local tmod = titemcrafted[1]
  376. local titem = titemcrafted[2]
  377. if not tmod or not titem or not data.craft[tmod] or not data.craft[tmod][titem] then
  378. -- table running failed!
  379. elseif data.craft[tmod][titem] > entry.target-1 then
  380. return entry.award
  381. end
  382. elseif lottachievements.get_total_item_count(data, "craft") > entry.target-1 then
  383. return entry.award
  384. end
  385. end
  386. end)
  387. end)
  388. minetest.register_on_dieplayer(function(player)
  389. -- Run checks
  390. local name = player:get_player_name()
  391. if not player or not name or name=="" then
  392. return
  393. end
  394. -- Get player
  395. lottachievements.assertPlayer(name)
  396. local data = lottachievements.players[name]
  397. -- Increment counter
  398. data.deaths = data.deaths + 1
  399. lottachievements.run_trigger_callbacks(player, data, "death", function(entry)
  400. if entry.target and entry.award and data.deaths and
  401. data.deaths >= entry.target then
  402. return entry.award
  403. end
  404. end)
  405. end)
  406. minetest.register_on_joinplayer(function(player)
  407. -- Run checks
  408. local name = player:get_player_name()
  409. if not player or not name or name=="" then
  410. return
  411. end
  412. -- Get player
  413. lottachievements.assertPlayer(name)
  414. local data = lottachievements.players[name]
  415. -- Increment counter
  416. data.joins = data.joins + 1
  417. lottachievements.run_trigger_callbacks(player, data, "join", function(entry)
  418. if entry.target and entry.award and data.joins and
  419. data.joins >= entry.target then
  420. return entry.award
  421. end
  422. end)
  423. end)
  424. minetest.register_on_chat_message(function(name, message)
  425. -- Run checks
  426. local idx = string.find(message,"/")
  427. if not name or (idx ~= nil and idx <= 1) then
  428. return
  429. end
  430. -- Get player
  431. lottachievements.assertPlayer(name)
  432. local data = lottachievements.players[name]
  433. local player = minetest.get_player_by_name(name)
  434. -- Increment counter
  435. data.chats = data.chats + 1
  436. lottachievements.run_trigger_callbacks(player, data, "chat", function(entry)
  437. if entry.target and entry.award and data.chats and
  438. data.chats >= entry.target then
  439. return entry.award
  440. end
  441. end)
  442. end)
  443. function lottachievements.equip(stack, player, count)
  444. if not stack or not player or not count then
  445. return
  446. end
  447. local data = lottachievements.players[player:get_player_name()]
  448. local name = string.split(stack:get_name(), ":")
  449. local name1 = name[1]
  450. local name2 = string.split(name[2], "_", false, 1)[2]
  451. if name1 and name2 then
  452. name = name1 .. ":" .. name2
  453. else
  454. return
  455. end
  456. if not lottachievements.increment_item_counter(data, "equip", name, count) then
  457. return
  458. end
  459. lottachievements.run_trigger_callbacks(player, data, "equip", function(entry)
  460. if entry.item then
  461. local titemequipped = string.split(entry.item, ":")
  462. local tmod = titemequipped[1]
  463. local titem = string.split(titemequipped[2], "_", false, 1)[2]
  464. if not tmod or not titem or not data.equip[tmod] or not data.equip[tmod][titem] then
  465. -- table running failed!
  466. elseif data.equip[tmod][titem] > 3 then
  467. return entry.award
  468. end
  469. end
  470. end)
  471. end
  472. function lottachievements.kill(name, player)
  473. if not name or not player or not player:is_player() then
  474. return
  475. end
  476. local data = lottachievements.players[player:get_player_name()]
  477. if string.find(name, "%d", -1) then
  478. -- For various types of mobs with multiple variations
  479. -- (e.g. The 3 different types of dwarves in armour, lottmobs:dwarf, lottmobs:dwarf1...)
  480. name = string.sub(name, 1, -2)
  481. end
  482. if not lottachievements.increment_item_counter(data, "kill", name) then
  483. return
  484. end
  485. lottachievements.run_trigger_callbacks(player, data, "kill", function(entry)
  486. if entry.mob then
  487. local tmobkilled = string.split(entry.mob, ":")
  488. local tmod = tmobkilled[1]
  489. local tmob = tmobkilled[2]
  490. if not tmod or not tmob or not data.kill[tmod] or not data.kill[tmod][tmob] then
  491. -- table running failed!
  492. elseif data.kill[tmod][tmob] > entry.target-1 then
  493. return entry.award
  494. end
  495. end
  496. end)
  497. end