--[[ Mana 0.2.0 This mod adds mana to players, a special attribute License: WTFPL ]] --[===[ Initialization ]===] mana = {} mana.playerlist = {} --[===[ API functions ]===] --[[ Sets the mana reserves of the specified player It is ensured that the resulting value will always be within the bounds of [0, maxmana] ]] function mana.set(playername, value) if value < 0 then minetest.log("info", "[mana] Warning: mana.set was called with negative value!") value = 0 end if value > mana.playerlist[playername].maxmana then value = mana.playerlist[playername].maxmana end if mana.playerlist[playername].mana ~= value then mana.playerlist[playername].mana = value mana.hud_update(playername) end end --[[ Sets the maximum mana of the specified player. The value must be positive or 0. The player's mana reserves will be capped at the new maximum, if neccessary. ]] function mana.setmax(playername, value) if value < 0 then value = 0 minetest.log("info", "[mana] Warning: mana.setmax was called with negative value!") end if mana.playerlist[playername].maxmana ~= value then mana.playerlist[playername].maxmana = value if(mana.playerlist[playername].mana > value) then mana.playerlist[playername].mana = value end mana.hud_update(playername) end end -- Returns the current mana of the specified player function mana.get(playername) return mana.playerlist[playername].mana end -- Returns the maximum mana of the specified player function mana.getmax(playername) return mana.playerlist[playername].maxmana end --[[ Adds up to the specified amount of mana to the player. If the sum would be greater than the maximum, the new mana amount will be capped at the maximum. returns: - true, excess on success, where excess is the amount of mana which was no - false on failure ]] function mana.add_up_to(playername, value) local t = mana.playerlist[playername] if(t ~= nil and value >= 0) then local excess if((t.mana + value) > t.maxmana) then excess = (t.mana + value) - t.maxmana t.mana = t.maxmana else excess = 0 t.mana = t.mana + value end mana.hud_update(playername) return true, excess else return false end end --[[ Adds the specified amount of mana to the player, iff it would not exceed the maximum. returns: - true on success, all mana has been added - false on failure, no mana has been added ]] function mana.add(playername, value) local t = mana.playerlist[playername] if(t ~= nil and ((t.mana + value) <= t.maxmana) and value >= 0) then t.mana = t.mana + value mana.hud_update(playername) return true else return false end end --[[ Subtracts the specified amount of mana from the player, iff the player has enough mana reserves. returns: - true on success, all mana has been subtracted - false on failure, no mana has been subtracted ]] function mana.subtract(playername, value) local t = mana.playerlist[playername] if(t ~= nil and t.mana >= value and value >= 0) then t.mana = t.mana -value mana.hud_update(playername) return true else return false end end --[[ Subtracts up to the specified amount of mana from the player. returns: - true, missing on success, where missing is the amount of mana which could not been subtracted - false on failure, no mana has been subtracted ]] function mana.subtract_up_to(playername, value) local t = mana.playerlist[playername] if(t ~= nil and value >= 0) then local missing if((t.mana - value) < 0) then missing = math.abs(t.mana - value) t.mana = 0 else missing = 0 t.mana = t.mana - value end mana.hud_update(playername) return true, missing else return false end end --[===[ File handling, loading data, saving data, setting up stuff for players. ]===] -- Load the playerlist from a previous session, if available. do local filepath = minetest.get_worldpath().."/mana.mt" local file = io.open(filepath, "r") if file then minetest.log("action", "[mana] mana.mt opened.") local string = file:read() io.close(file) if(string ~= nil) then local savetable = minetest.deserialize(string) mana.playerlist = savetable.playerlist minetest.debug("[mana] mana.mt successfully read.") end end end function mana.save_to_file() local savetable = {} savetable.playerlist = mana.playerlist local savestring = minetest.serialize(savetable) local filepath = minetest.get_worldpath().."/mana.mt" local file = io.open(filepath, "w") if file then file:write(savestring) io.close(file) minetest.log("action", "[mana] Wrote mana data into "..filepath..".") else minetest.log("error", "[mana] Failed to write mana data into "..filepath..".") end end minetest.register_on_dieplayer(function(player) local playername = player:get_player_name() mana.set(playername, 0) mana.hud_update(playername) end) minetest.register_on_leaveplayer(function(player) local playername = player:get_player_name() mana.hud_remove(playername) mana.playerlist[playername] = nil end) minetest.register_on_shutdown(function() minetest.log("action", "[mana] Server shuts down. Rescuing data into mana.mt") mana.save_to_file() end) minetest.register_on_joinplayer(function(player) local playername = player:get_player_name() if mana.playerlist[playername] == nil then mana.playerlist[playername] = {} mana.playerlist[playername].mana = 0 mana.playerlist[playername].maxmana = 100 end if minetest.get_modpath("hudbars") ~= nil then hud.hudtables.mana.add_all(player, mana.get(playername), mana.getmax(playername)) else mana.hud_add(playername) end end) --[===[ HUD functions ]===] if minetest.get_modpath("hudbars") ~= nil then hud.register_hudbar("mana", 0xFFFFFF, "Mana", { bar = "mana_bar.png", icon = "mana_icon.png" }, 0, 100, false) function mana.hud_update(playername) local player = minetest.get_player_by_name(playername) hud.change_hudbar(player, hud.hudtables.mana, mana.get(playername), mana.getmax(playername)) end else function mana.manastring(playername) return string.format("Mana: %d/%d", mana.get(playername), mana.getmax(playername)) end function mana.hud_add(playername) local player = minetest.get_player_by_name(playername) id = player:hud_add({ hud_elem_type = "text", position = { x = 0.5, y=0.9 }, text = mana.manastring(playername), scale = { x = 0, y = 0 }, alignment = { x = 1, y = 0}, direction = 1, number = 0xFFFFFF, offset = { x = -200, y = 15} }) mana.playerlist[playername].hudid = id return id end function mana.hud_update(playername) local player = minetest.get_player_by_name(playername) player:hud_change(mana.playerlist[playername].hudid, "number", mana.get(playername)) end function mana.hud_remove(playername) local player = minetest.get_player_by_name(playername) player:hud_remove(mana.playerlist[playername].hudid) end end