Regen can now be a float and negative
[minetest_mana.git] / init.lua
blob64ce5db8f62a79909693e21872129b9da6d15882
1 --[[
2 Mana 1.0.2
3 This mod adds mana to players, a special attribute
5 License: WTFPL
6 ]]
8 --[===[
9 Initialization
10 ]===]
12 mana = {}
13 mana.playerlist = {}
15 mana.settings = {}
16 mana.settings.default_max = 200
17 mana.settings.default_regen = 1
18 mana.settings.regen_timer = 0.2
21 local default_max = tonumber(minetest.setting_get("mana_default_max"))
22 if default_max ~= nil then
23 mana.settings.default_max = default_max
24 end
26 local default_regen = tonumber(minetest.setting_get("mana_default_regen"))
27 if default_regen ~= nil then
28 mana.settings.default_regen = default_regen
29 end
31 local regen_timer = tonumber(minetest.setting_get("mana_regen_timer"))
32 if regen_timer ~= nil then
33 mana.settings.regen_timer = regen_timer
34 end
35 end
38 --[===[
39 API functions
40 ]===]
42 function mana.set(playername, value)
43 if value < 0 then
44 minetest.log("info", "[mana] Warning: mana.set was called with negative value!")
45 value = 0
46 end
47 value = mana.round(value)
48 if value > mana.playerlist[playername].maxmana then
49 value = mana.playerlist[playername].maxmana
50 end
51 if mana.playerlist[playername].mana ~= value then
52 mana.playerlist[playername].mana = value
53 mana.hud_update(playername)
54 end
55 end
57 function mana.setmax(playername, value)
58 if value < 0 then
59 value = 0
60 minetest.log("info", "[mana] Warning: mana.setmax was called with negative value!")
61 end
62 value = mana.round(value)
63 if mana.playerlist[playername].maxmana ~= value then
64 mana.playerlist[playername].maxmana = value
65 if(mana.playerlist[playername].mana > value) then
66 mana.playerlist[playername].mana = value
67 end
68 mana.hud_update(playername)
69 end
70 end
72 function mana.setregen(playername, value)
73 mana.playerlist[playername].regen = value
74 end
76 function mana.get(playername)
77 return mana.playerlist[playername].mana
78 end
80 function mana.getmax(playername)
81 return mana.playerlist[playername].maxmana
82 end
84 function mana.getregen(playername)
85 return mana.playerlist[playername].regen
86 end
88 function mana.add_up_to(playername, value)
89 local t = mana.playerlist[playername]
90 value = mana.round(value)
91 if(t ~= nil and value >= 0) then
92 local excess
93 if((t.mana + value) > t.maxmana) then
94 excess = (t.mana + value) - t.maxmana
95 t.mana = t.maxmana
96 else
97 excess = 0
98 t.mana = t.mana + value
99 end
100 mana.hud_update(playername)
101 return true, excess
102 else
103 return false
107 function mana.add(playername, value)
108 local t = mana.playerlist[playername]
109 value = mana.round(value)
110 if(t ~= nil and ((t.mana + value) <= t.maxmana) and value >= 0) then
111 t.mana = t.mana + value
112 mana.hud_update(playername)
113 return true
114 else
115 return false
119 function mana.subtract(playername, value)
120 local t = mana.playerlist[playername]
121 value = mana.round(value)
122 if(t ~= nil and t.mana >= value and value >= 0) then
123 t.mana = t.mana -value
124 mana.hud_update(playername)
125 return true
126 else
127 return false
131 function mana.subtract_up_to(playername, value)
132 local t = mana.playerlist[playername]
133 value = mana.round(value)
134 if(t ~= nil and value >= 0) then
135 local missing
136 if((t.mana - value) < 0) then
137 missing = math.abs(t.mana - value)
138 t.mana = 0
139 else
140 missing = 0
141 t.mana = t.mana - value
143 mana.hud_update(playername)
144 return true, missing
145 else
146 return false
154 --[===[
155 File handling, loading data, saving data, setting up stuff for players.
156 ]===]
159 -- Load the playerlist from a previous session, if available.
161 local filepath = minetest.get_worldpath().."/mana.mt"
162 local file = io.open(filepath, "r")
163 if file then
164 minetest.log("action", "[mana] mana.mt opened.")
165 local string = file:read()
166 io.close(file)
167 if(string ~= nil) then
168 local savetable = minetest.deserialize(string)
169 mana.playerlist = savetable.playerlist
170 minetest.debug("[mana] mana.mt successfully read.")
175 function mana.save_to_file()
176 local savetable = {}
177 savetable.playerlist = mana.playerlist
179 local savestring = minetest.serialize(savetable)
181 local filepath = minetest.get_worldpath().."/mana.mt"
182 local file = io.open(filepath, "w")
183 if file then
184 file:write(savestring)
185 io.close(file)
186 minetest.log("action", "[mana] Wrote mana data into "..filepath..".")
187 else
188 minetest.log("error", "[mana] Failed to write mana data into "..filepath..".")
193 minetest.register_on_respawnplayer(function(player)
194 local playername = player:get_player_name()
195 mana.set(playername, 0)
196 mana.hud_update(playername)
197 end)
200 minetest.register_on_leaveplayer(function(player)
201 local playername = player:get_player_name()
202 if not minetest.get_modpath("hudbars") ~= nil then
203 mana.hud_remove(playername)
205 mana.save_to_file()
206 end)
208 minetest.register_on_shutdown(function()
209 minetest.log("action", "[mana] Server shuts down. Rescuing data into mana.mt")
210 mana.save_to_file()
211 end)
213 minetest.register_on_joinplayer(function(player)
214 local playername = player:get_player_name()
216 if mana.playerlist[playername] == nil then
217 mana.playerlist[playername] = {}
218 mana.playerlist[playername].mana = 0
219 mana.playerlist[playername].maxmana = mana.settings.default_max
220 mana.playerlist[playername].regen = mana.settings.default_regen
221 mana.playerlist[playername].remainder = 0
224 if minetest.get_modpath("hudbars") ~= nil then
225 hb.init_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
226 else
227 mana.hud_add(playername)
229 end)
232 --[===[
233 Mana regeneration
234 ]===]
236 mana.regen_timer = 0
238 minetest.register_globalstep(function(dtime)
239 mana.regen_timer = mana.regen_timer + dtime
240 if mana.regen_timer >= mana.settings.regen_timer then
241 local factor = math.floor(mana.regen_timer / mana.settings.regen_timer)
242 local players = minetest.get_connected_players()
243 for i=1, #players do
244 local name = players[i]:get_player_name()
245 if mana.playerlist[name] ~= nil then
246 if players[i]:get_hp() > 0 then
247 local plus = mana.playerlist[name].regen * factor
248 -- Compability check for version <= 1.0.2 which did not have the remainder field
249 if mana.playerlist[name].remainder ~= nil then
250 plus = plus + mana.playerlist[name].remainder
252 local plus_now = math.floor(plus)
253 local floor = plus - plus_now
254 if plus_now > 0 then
255 mana.add_up_to(name, plus_now)
256 else
257 mana.subtract_up_to(name, math.abs(plus_now))
259 mana.playerlist[name].remainder = floor
263 mana.regen_timer = mana.regen_timer % mana.settings.regen_timer
265 end)
267 --[===[
268 HUD functions
269 ]===]
271 if minetest.get_modpath("hudbars") ~= nil then
272 hb.register_hudbar("mana", 0xFFFFFF, "Mana", { bar = "mana_bar.png", icon = "mana_icon.png", bgicon = "mana_bgicon.png" }, 0, mana.settings.default_max, false)
274 function mana.hud_update(playername)
275 local player = minetest.get_player_by_name(playername)
276 if player ~= nil then
277 hb.change_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
281 function mana.hud_remove(playername)
284 else
285 function mana.manastring(playername)
286 return string.format("Mana: %d/%d", mana.get(playername), mana.getmax(playername))
289 function mana.hud_add(playername)
290 local player = minetest.get_player_by_name(playername)
291 id = player:hud_add({
292 hud_elem_type = "text",
293 position = { x = 0.5, y=1 },
294 text = mana.manastring(playername),
295 scale = { x = 0, y = 0 },
296 alignment = { x = 1, y = 0},
297 direction = 1,
298 number = 0xFFFFFF,
299 offset = { x = -262, y = -103}
301 mana.playerlist[playername].hudid = id
302 return id
305 function mana.hud_update(playername)
306 local player = minetest.get_player_by_name(playername)
307 player:hud_change(mana.playerlist[playername].hudid, "text", mana.manastring(playername))
310 function mana.hud_remove(playername)
311 local player = minetest.get_player_by_name(playername)
312 player:hud_remove(mana.playerlist[playername].hudid)
316 --[===[
317 Helper functions
318 ]===]
319 mana.round = function(x)
320 return math.ceil(math.floor(x+0.5))