minetest_mana/init.lua

282 lines
6.7 KiB
Lua

--[[
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