init.lua 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. --[[
  2. Mana
  3. This mod adds mana to players, a special attribute
  4. License: WTFPL
  5. ]]
  6. --[===[
  7. Initialization
  8. ]===]
  9. local S
  10. if (minetest.get_modpath("intllib")) then
  11. S = intllib.Getter()
  12. else
  13. S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end
  14. end
  15. mana = {}
  16. mana.playerlist = {}
  17. mana.settings = {}
  18. mana.settings.default_max = 200
  19. mana.settings.default_regen = 1
  20. mana.settings.regen_timer = 0.2
  21. do
  22. local default_max = tonumber(minetest.settings:get("mana_default_max"))
  23. if default_max ~= nil then
  24. mana.settings.default_max = default_max
  25. end
  26. local default_regen = tonumber(minetest.settings:get("mana_default_regen"))
  27. if default_regen ~= nil then
  28. mana.settings.default_regen = default_regen
  29. end
  30. local regen_timer = tonumber(minetest.settings:get("mana_regen_timer"))
  31. if regen_timer ~= nil then
  32. mana.settings.regen_timer = regen_timer
  33. end
  34. end
  35. --[===[
  36. API functions
  37. ]===]
  38. function mana.set(playername, value)
  39. if value < 0 then
  40. minetest.log("info", "[mana] Warning: mana.set was called with negative value!")
  41. value = 0
  42. end
  43. value = mana.round(value)
  44. if value > mana.playerlist[playername].maxmana then
  45. value = mana.playerlist[playername].maxmana
  46. end
  47. if mana.playerlist[playername].mana ~= value then
  48. mana.playerlist[playername].mana = value
  49. mana.hud_update(playername)
  50. end
  51. end
  52. function mana.setmax(playername, value)
  53. if value < 0 then
  54. value = 0
  55. minetest.log("info", "[mana] Warning: mana.setmax was called with negative value!")
  56. end
  57. value = mana.round(value)
  58. if mana.playerlist[playername].maxmana ~= value then
  59. mana.playerlist[playername].maxmana = value
  60. if(mana.playerlist[playername].mana > value) then
  61. mana.playerlist[playername].mana = value
  62. end
  63. mana.hud_update(playername)
  64. end
  65. end
  66. function mana.setregen(playername, value)
  67. mana.playerlist[playername].regen = value
  68. end
  69. function mana.get(playername)
  70. return mana.playerlist[playername].mana
  71. end
  72. function mana.getmax(playername)
  73. return mana.playerlist[playername].maxmana
  74. end
  75. function mana.getregen(playername)
  76. return mana.playerlist[playername].regen
  77. end
  78. function mana.add_up_to(playername, value)
  79. local t = mana.playerlist[playername]
  80. value = mana.round(value)
  81. if(t ~= nil and value >= 0) then
  82. local excess
  83. if((t.mana + value) > t.maxmana) then
  84. excess = (t.mana + value) - t.maxmana
  85. t.mana = t.maxmana
  86. else
  87. excess = 0
  88. t.mana = t.mana + value
  89. end
  90. mana.hud_update(playername)
  91. return true, excess
  92. else
  93. return false
  94. end
  95. end
  96. function mana.add(playername, value)
  97. local t = mana.playerlist[playername]
  98. value = mana.round(value)
  99. if(t ~= nil and ((t.mana + value) <= t.maxmana) and value >= 0) then
  100. t.mana = t.mana + value
  101. mana.hud_update(playername)
  102. return true
  103. else
  104. return false
  105. end
  106. end
  107. function mana.subtract(playername, value)
  108. local t = mana.playerlist[playername]
  109. value = mana.round(value)
  110. if(t ~= nil and t.mana >= value and value >= 0) then
  111. t.mana = t.mana -value
  112. mana.hud_update(playername)
  113. return true
  114. else
  115. return false
  116. end
  117. end
  118. function mana.subtract_up_to(playername, value)
  119. local t = mana.playerlist[playername]
  120. value = mana.round(value)
  121. if(t ~= nil and value >= 0) then
  122. local missing
  123. if((t.mana - value) < 0) then
  124. missing = math.abs(t.mana - value)
  125. t.mana = 0
  126. else
  127. missing = 0
  128. t.mana = t.mana - value
  129. end
  130. mana.hud_update(playername)
  131. return true, missing
  132. else
  133. return false
  134. end
  135. end
  136. --[===[
  137. File handling, loading data, saving data, setting up stuff for players.
  138. ]===]
  139. -- Load the playerlist from a previous session, if available.
  140. do
  141. local filepath = minetest.get_worldpath().."/mana.mt"
  142. local file = io.open(filepath, "r")
  143. if file then
  144. minetest.log("action", "[mana] mana.mt opened.")
  145. local string = file:read()
  146. io.close(file)
  147. if(string ~= nil) then
  148. local savetable = minetest.deserialize(string)
  149. mana.playerlist = savetable.playerlist
  150. minetest.debug("[mana] mana.mt successfully read.")
  151. end
  152. end
  153. end
  154. function mana.save_to_file()
  155. local savetable = {}
  156. savetable.playerlist = mana.playerlist
  157. local savestring = minetest.serialize(savetable)
  158. local filepath = minetest.get_worldpath().."/mana.mt"
  159. local file = io.open(filepath, "w")
  160. if file then
  161. file:write(savestring)
  162. io.close(file)
  163. minetest.log("action", "[mana] Wrote mana data into "..filepath..".")
  164. else
  165. minetest.log("error", "[mana] Failed to write mana data into "..filepath..".")
  166. end
  167. end
  168. minetest.register_on_respawnplayer(function(player)
  169. local playername = player:get_player_name()
  170. mana.set(playername, 0)
  171. mana.hud_update(playername)
  172. end)
  173. minetest.register_on_leaveplayer(function(player)
  174. local playername = player:get_player_name()
  175. if not minetest.get_modpath("hudbars") ~= nil then
  176. mana.hud_remove(playername)
  177. end
  178. mana.save_to_file()
  179. end)
  180. minetest.register_on_shutdown(function()
  181. minetest.log("action", "[mana] Server shuts down. Rescuing data into mana.mt")
  182. mana.save_to_file()
  183. end)
  184. minetest.register_on_joinplayer(function(player)
  185. local playername = player:get_player_name()
  186. if mana.playerlist[playername] == nil then
  187. mana.playerlist[playername] = {}
  188. mana.playerlist[playername].mana = 0
  189. mana.playerlist[playername].maxmana = mana.settings.default_max
  190. mana.playerlist[playername].regen = mana.settings.default_regen
  191. mana.playerlist[playername].remainder = 0
  192. end
  193. if minetest.get_modpath("hudbars") ~= nil then
  194. hb.init_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
  195. else
  196. mana.hud_add(playername)
  197. end
  198. end)
  199. --[===[
  200. Mana regeneration
  201. ]===]
  202. mana.regen_timer = 0
  203. minetest.register_globalstep(function(dtime)
  204. mana.regen_timer = mana.regen_timer + dtime
  205. if mana.regen_timer >= mana.settings.regen_timer then
  206. local factor = math.floor(mana.regen_timer / mana.settings.regen_timer)
  207. local players = minetest.get_connected_players()
  208. for i=1, #players do
  209. local name = players[i]:get_player_name()
  210. if mana.playerlist[name] ~= nil then
  211. if players[i]:get_hp() > 0 then
  212. local plus = mana.playerlist[name].regen * factor
  213. -- Compability check for version <= 1.0.2 which did not have the remainder field
  214. if mana.playerlist[name].remainder ~= nil then
  215. plus = plus + mana.playerlist[name].remainder
  216. end
  217. local plus_now = math.floor(plus)
  218. local floor = plus - plus_now
  219. if plus_now > 0 then
  220. mana.add_up_to(name, plus_now)
  221. else
  222. mana.subtract_up_to(name, math.abs(plus_now))
  223. end
  224. mana.playerlist[name].remainder = floor
  225. end
  226. end
  227. end
  228. mana.regen_timer = mana.regen_timer % mana.settings.regen_timer
  229. end
  230. end)
  231. --[===[
  232. HUD functions
  233. ]===]
  234. if minetest.get_modpath("hudbars") ~= nil then
  235. hb.register_hudbar("mana", 0xFFFFFF, S("Mana"), { bar = "mana_bar.png", icon = "mana_icon.png", bgicon = "mana_bgicon.png" }, 0, mana.settings.default_max, false)
  236. function mana.hud_update(playername)
  237. local player = minetest.get_player_by_name(playername)
  238. if player ~= nil then
  239. hb.change_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
  240. end
  241. end
  242. function mana.hud_remove(playername)
  243. end
  244. else
  245. function mana.manastring(playername)
  246. return S("Mana: @1/@2", mana.get(playername), mana.getmax(playername))
  247. end
  248. function mana.hud_add(playername)
  249. local player = minetest.get_player_by_name(playername)
  250. local id = player:hud_add({
  251. hud_elem_type = "text",
  252. position = { x = 0.5, y=1 },
  253. text = mana.manastring(playername),
  254. scale = { x = 0, y = 0 },
  255. alignment = { x = 1, y = 0},
  256. direction = 1,
  257. number = 0xFFFFFF,
  258. offset = { x = -262, y = -103}
  259. })
  260. mana.playerlist[playername].hudid = id
  261. return id
  262. end
  263. function mana.hud_update(playername)
  264. local player = minetest.get_player_by_name(playername)
  265. player:hud_change(mana.playerlist[playername].hudid, "text", mana.manastring(playername))
  266. end
  267. function mana.hud_remove(playername)
  268. local player = minetest.get_player_by_name(playername)
  269. player:hud_remove(mana.playerlist[playername].hudid)
  270. end
  271. end
  272. --[===[
  273. Helper functions
  274. ]===]
  275. mana.round = function(x)
  276. return math.ceil(math.floor(x+0.5))
  277. end