init.lua 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. --[[
  2. Mana
  3. This mod adds mana to players, a special attribute
  4. License: MIT License
  5. ]]
  6. --[===[
  7. Initialization
  8. ]===]
  9. local S = minetest.get_translator("hbmana")
  10. hbmana = {}
  11. hbmana.playerlist = {}
  12. hbmana.settings = {}
  13. hbmana.settings.default_max = 10
  14. hbmana.settings.max_reachable = 100
  15. hbmana.settings.default_regen = 1
  16. hbmana.settings.regen_timer = 0.4
  17. do
  18. local default_max = tonumber(minetest.settings:get("hbmana_default_max"))
  19. if default_max ~= nil then
  20. hbmana.settings.default_max = default_max
  21. end
  22. local max_reachable = tonumber(minetest.settings:get("hbmana_max_mana"))
  23. if max_reachable ~= nil then
  24. hbmana.settings.max_reachable = max_reachable
  25. end
  26. local default_regen = tonumber(minetest.settings:get("hbmana_default_regen"))
  27. if default_regen ~= nil then
  28. hbmana.settings.default_regen = default_regen
  29. end
  30. local regen_timer = tonumber(minetest.settings:get("hbmana_regen_timer"))
  31. if regen_timer ~= nil then
  32. hbmana.settings.regen_timer = regen_timer
  33. end
  34. end
  35. --[===[
  36. API functions
  37. ]===]
  38. function hbmana.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 = hbmana.round(value)
  44. if value > hbmana.playerlist[playername].maxmana then
  45. value = hbmana.playerlist[playername].maxmana
  46. end
  47. if hbmana.playerlist[playername].mana ~= value then
  48. hbmana.playerlist[playername].mana = value
  49. hbmana.hud_update(playername)
  50. end
  51. end
  52. function hbmana.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 = hbmana.round(value)
  58. if hbmana.playerlist[playername].maxmana ~= value and hbmana.settings.max_reachable >= value then
  59. hbmana.playerlist[playername].maxmana = value
  60. if(hbmana.playerlist[playername].mana > value) then
  61. hbmana.playerlist[playername].mana = value
  62. end
  63. hbmana.hud_update(playername)
  64. end
  65. end
  66. function hbmana.setregen(playername, value)
  67. hbmana.playerlist[playername].regen = value
  68. end
  69. function hbmana.get(playername)
  70. return hbmana.playerlist[playername].mana
  71. end
  72. function hbmana.getmax(playername)
  73. return hbmana.playerlist[playername].maxmana
  74. end
  75. function hbmana.getregen(playername)
  76. return hbmana.playerlist[playername].regen
  77. end
  78. function hbmana.add_up_to(playername, value)
  79. local t = hbmana.playerlist[playername]
  80. value = hbmana.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. hbmana.hud_update(playername)
  91. return true, excess
  92. else
  93. return false
  94. end
  95. end
  96. function hbmana.add(playername, value)
  97. local t = hbmana.playerlist[playername]
  98. value = hbmana.round(value)
  99. if(t ~= nil and ((t.mana + value) <= t.maxmana) and value >= 0) then
  100. t.mana = t.mana + value
  101. hbmana.hud_update(playername)
  102. return true
  103. else
  104. return false
  105. end
  106. end
  107. function hbmana.subtract(playername, value)
  108. local t = hbmana.playerlist[playername]
  109. value = hbmana.round(value)
  110. if(t ~= nil and t.mana >= value and value >= 0) then
  111. t.mana = t.mana -value
  112. hbmana.hud_update(playername)
  113. return true
  114. else
  115. return false
  116. end
  117. end
  118. function hbmana.subtract_up_to(playername, value)
  119. local t = hbmana.playerlist[playername]
  120. value = hbmana.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. hbmana.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. hbmana.playerlist = savetable.playerlist
  150. minetest.log("action", "[mana] mana.mt successfully read.")
  151. end
  152. end
  153. end
  154. function hbmana.save_to_file()
  155. local savetable = {}
  156. savetable.playerlist = hbmana.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. hbmana.set(playername, 0)
  171. hbmana.hud_update(playername)
  172. end)
  173. minetest.register_on_leaveplayer(function(player)
  174. local playername = player:get_player_name()
  175. hbmana.save_to_file()
  176. end)
  177. minetest.register_on_shutdown(function()
  178. -- reset regeneration rate
  179. for k,v in pairs(hbmana.playerlist) do
  180. v.regen = hbmana.settings.default_regen
  181. end
  182. minetest.log("action", "[mana] Server shuts down. Rescuing data into mana.mt")
  183. hbmana.save_to_file()
  184. end)
  185. minetest.register_on_joinplayer(function(player)
  186. local playername = player:get_player_name()
  187. if hbmana.playerlist[playername] == nil then
  188. hbmana.playerlist[playername] = {}
  189. hbmana.playerlist[playername].mana = 0
  190. hbmana.playerlist[playername].maxmana = hbmana.settings.default_max
  191. hbmana.playerlist[playername].regen = hbmana.settings.default_regen
  192. hbmana.playerlist[playername].remainder = 0
  193. end
  194. hb.init_hudbar(player, "mana", hbmana.get(playername), hbmana.getmax(playername))
  195. end)
  196. --[===[
  197. Mana regeneration
  198. ]===]
  199. hbmana.regen_timer = 0
  200. minetest.register_globalstep(function(dtime)
  201. hbmana.regen_timer = hbmana.regen_timer + dtime
  202. if hbmana.regen_timer >= hbmana.settings.regen_timer then
  203. local factor = math.floor(hbmana.regen_timer / hbmana.settings.regen_timer)
  204. local players = minetest.get_connected_players()
  205. for i=1, #players do
  206. local name = players[i]:get_player_name()
  207. if hbmana.playerlist[name] ~= nil then
  208. if players[i]:get_hp() > 0 then
  209. local plus = hbmana.playerlist[name].regen * factor
  210. -- Compability check for version <= 1.0.2 which did not have the remainder field
  211. if hbmana.playerlist[name].remainder ~= nil then
  212. plus = plus + hbmana.playerlist[name].remainder
  213. end
  214. local plus_now = math.floor(plus)
  215. local floor = plus - plus_now
  216. if plus_now > 0 then
  217. hbmana.add_up_to(name, plus_now)
  218. else
  219. hbmana.subtract_up_to(name, math.abs(plus_now))
  220. end
  221. hbmana.playerlist[name].remainder = floor
  222. end
  223. end
  224. end
  225. hbmana.regen_timer = hbmana.regen_timer % hbmana.settings.regen_timer
  226. end
  227. end)
  228. --[===[
  229. HUD functions
  230. ]===]
  231. hb.register_hudbar("mana", 0xFFFFFF, S("Mana"), { bar = "mana_bar.png", icon = "mana_icon.png", bgicon = "mana_bgicon.png" }, 0, hbmana.settings.default_max, false)
  232. function hbmana.hud_update(playername)
  233. local player = minetest.get_player_by_name(playername)
  234. if player ~= nil then
  235. hb.change_hudbar(player, "mana", hbmana.get(playername), hbmana.getmax(playername))
  236. end
  237. end
  238. --[===[
  239. Helper functions
  240. ]===]
  241. hbmana.round = function(x)
  242. return math.ceil(math.floor(x+0.5))
  243. end