Version 1.3.1
[minetest_mana.git] / init.lua
blob85e0c6236711c6ad0374bd38f23c75fd0bab368d
1 --[[
2 Mana
3 This mod adds mana to players, a special attribute
5 License: MIT License
6 ]]
8 --[===[
9 Initialization
10 ]===]
12 local S = minetest.get_translator("mana")
14 mana = {}
15 mana.playerlist = {}
17 mana.settings = {}
18 mana.settings.default_max = 200
19 mana.settings.default_regen = 1
20 mana.settings.regen_timer = 0.2
23 local default_max = tonumber(minetest.settings:get("mana_default_max"))
24 if default_max ~= nil then
25 mana.settings.default_max = default_max
26 end
28 local default_regen = tonumber(minetest.settings:get("mana_default_regen"))
29 if default_regen ~= nil then
30 mana.settings.default_regen = default_regen
31 end
33 local regen_timer = tonumber(minetest.settings:get("mana_regen_timer"))
34 if regen_timer ~= nil then
35 mana.settings.regen_timer = regen_timer
36 end
37 end
40 --[===[
41 API functions
42 ]===]
44 function mana.set(playername, value)
45 if value < 0 then
46 minetest.log("info", "[mana] Warning: mana.set was called with negative value!")
47 value = 0
48 end
49 value = mana.round(value)
50 if value > mana.playerlist[playername].maxmana then
51 value = mana.playerlist[playername].maxmana
52 end
53 if mana.playerlist[playername].mana ~= value then
54 mana.playerlist[playername].mana = value
55 mana.hud_update(playername)
56 end
57 end
59 function mana.setmax(playername, value)
60 if value < 0 then
61 value = 0
62 minetest.log("info", "[mana] Warning: mana.setmax was called with negative value!")
63 end
64 value = mana.round(value)
65 if mana.playerlist[playername].maxmana ~= value then
66 mana.playerlist[playername].maxmana = value
67 if(mana.playerlist[playername].mana > value) then
68 mana.playerlist[playername].mana = value
69 end
70 mana.hud_update(playername)
71 end
72 end
74 function mana.setregen(playername, value)
75 mana.playerlist[playername].regen = value
76 end
78 function mana.get(playername)
79 return mana.playerlist[playername].mana
80 end
82 function mana.getmax(playername)
83 return mana.playerlist[playername].maxmana
84 end
86 function mana.getregen(playername)
87 return mana.playerlist[playername].regen
88 end
90 function mana.add_up_to(playername, value)
91 local t = mana.playerlist[playername]
92 value = mana.round(value)
93 if(t ~= nil and value >= 0) then
94 local excess
95 if((t.mana + value) > t.maxmana) then
96 excess = (t.mana + value) - t.maxmana
97 t.mana = t.maxmana
98 else
99 excess = 0
100 t.mana = t.mana + value
102 mana.hud_update(playername)
103 return true, excess
104 else
105 return false
109 function mana.add(playername, value)
110 local t = mana.playerlist[playername]
111 value = mana.round(value)
112 if(t ~= nil and ((t.mana + value) <= t.maxmana) and value >= 0) then
113 t.mana = t.mana + value
114 mana.hud_update(playername)
115 return true
116 else
117 return false
121 function mana.subtract(playername, value)
122 local t = mana.playerlist[playername]
123 value = mana.round(value)
124 if(t ~= nil and t.mana >= value and value >= 0) then
125 t.mana = t.mana -value
126 mana.hud_update(playername)
127 return true
128 else
129 return false
133 function mana.subtract_up_to(playername, value)
134 local t = mana.playerlist[playername]
135 value = mana.round(value)
136 if(t ~= nil and value >= 0) then
137 local missing
138 if((t.mana - value) < 0) then
139 missing = math.abs(t.mana - value)
140 t.mana = 0
141 else
142 missing = 0
143 t.mana = t.mana - value
145 mana.hud_update(playername)
146 return true, missing
147 else
148 return false
156 --[===[
157 File handling, loading data, saving data, setting up stuff for players.
158 ]===]
161 -- Load the playerlist from a previous session, if available.
163 local filepath = minetest.get_worldpath().."/mana.mt"
164 local file = io.open(filepath, "r")
165 if file then
166 minetest.log("action", "[mana] mana.mt opened.")
167 local string = file:read()
168 io.close(file)
169 if(string ~= nil) then
170 local savetable = minetest.deserialize(string)
171 mana.playerlist = savetable.playerlist
172 minetest.debug("[mana] mana.mt successfully read.")
177 function mana.save_to_file()
178 local savetable = {}
179 savetable.playerlist = mana.playerlist
181 local savestring = minetest.serialize(savetable)
183 local filepath = minetest.get_worldpath().."/mana.mt"
184 local file = io.open(filepath, "w")
185 if file then
186 file:write(savestring)
187 io.close(file)
188 minetest.log("action", "[mana] Wrote mana data into "..filepath..".")
189 else
190 minetest.log("error", "[mana] Failed to write mana data into "..filepath..".")
195 minetest.register_on_respawnplayer(function(player)
196 local playername = player:get_player_name()
197 mana.set(playername, 0)
198 mana.hud_update(playername)
199 end)
202 minetest.register_on_leaveplayer(function(player)
203 local playername = player:get_player_name()
204 if not minetest.get_modpath("hudbars") ~= nil then
205 mana.hud_remove(playername)
207 mana.save_to_file()
208 end)
210 minetest.register_on_shutdown(function()
211 minetest.log("action", "[mana] Server shuts down. Rescuing data into mana.mt")
212 mana.save_to_file()
213 end)
215 minetest.register_on_joinplayer(function(player)
216 local playername = player:get_player_name()
218 if mana.playerlist[playername] == nil then
219 mana.playerlist[playername] = {}
220 mana.playerlist[playername].mana = 0
221 mana.playerlist[playername].maxmana = mana.settings.default_max
222 mana.playerlist[playername].regen = mana.settings.default_regen
223 mana.playerlist[playername].remainder = 0
226 if minetest.get_modpath("hudbars") ~= nil then
227 hb.init_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
228 else
229 mana.hud_add(playername)
231 end)
234 --[===[
235 Mana regeneration
236 ]===]
238 mana.regen_timer = 0
240 minetest.register_globalstep(function(dtime)
241 mana.regen_timer = mana.regen_timer + dtime
242 if mana.regen_timer >= mana.settings.regen_timer then
243 local factor = math.floor(mana.regen_timer / mana.settings.regen_timer)
244 local players = minetest.get_connected_players()
245 for i=1, #players do
246 local name = players[i]:get_player_name()
247 if mana.playerlist[name] ~= nil then
248 if players[i]:get_hp() > 0 then
249 local plus = mana.playerlist[name].regen * factor
250 -- Compability check for version <= 1.0.2 which did not have the remainder field
251 if mana.playerlist[name].remainder ~= nil then
252 plus = plus + mana.playerlist[name].remainder
254 local plus_now = math.floor(plus)
255 local floor = plus - plus_now
256 if plus_now > 0 then
257 mana.add_up_to(name, plus_now)
258 else
259 mana.subtract_up_to(name, math.abs(plus_now))
261 mana.playerlist[name].remainder = floor
265 mana.regen_timer = mana.regen_timer % mana.settings.regen_timer
267 end)
269 --[===[
270 HUD functions
271 ]===]
273 if minetest.get_modpath("hudbars") ~= nil then
274 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)
276 function mana.hud_update(playername)
277 local player = minetest.get_player_by_name(playername)
278 if player ~= nil then
279 hb.change_hudbar(player, "mana", mana.get(playername), mana.getmax(playername))
283 function mana.hud_remove(playername)
286 else
287 function mana.manastring(playername)
288 return S("Mana: @1/@2", mana.get(playername), mana.getmax(playername))
291 function mana.hud_add(playername)
292 local player = minetest.get_player_by_name(playername)
293 local id = player:hud_add({
294 hud_elem_type = "text",
295 position = { x = 0.5, y=1 },
296 text = mana.manastring(playername),
297 scale = { x = 0, y = 0 },
298 alignment = { x = 1, y = 0},
299 direction = 1,
300 number = 0xFFFFFF,
301 offset = { x = -262, y = -103}
303 mana.playerlist[playername].hudid = id
304 return id
307 function mana.hud_update(playername)
308 local player = minetest.get_player_by_name(playername)
309 player:hud_change(mana.playerlist[playername].hudid, "text", mana.manastring(playername))
312 function mana.hud_remove(playername)
313 local player = minetest.get_player_by_name(playername)
314 player:hud_remove(mana.playerlist[playername].hudid)
318 --[===[
319 Helper functions
320 ]===]
321 mana.round = function(x)
322 return math.ceil(math.floor(x+0.5))