From 1e3cb323c4956104a94daa8e4ff7eef6a323d021 Mon Sep 17 00:00:00 2001 From: LeMagnesium Date: Sun, 1 Mar 2015 11:40:25 +0100 Subject: [PATCH] Added mana and changed position in hotbar --- mods/mana/API.md | 120 ++++++++++++ mods/mana/README.txt | 51 +++++ mods/mana/depends.txt | 1 + mods/mana/description.txt | 1 + mods/mana/init.lua | 308 +++++++++++++++++++++++++++++++ mods/mana/textures/mana_bar.png | Bin 0 -> 80 bytes mods/mana/textures/mana_icon.png | Bin 0 -> 2994 bytes worlds/minetestforfun/world.mt | 1 - 8 files changed, 481 insertions(+), 1 deletion(-) create mode 100644 mods/mana/API.md create mode 100644 mods/mana/README.txt create mode 100644 mods/mana/depends.txt create mode 100644 mods/mana/description.txt create mode 100644 mods/mana/init.lua create mode 100644 mods/mana/textures/mana_bar.png create mode 100644 mods/mana/textures/mana_icon.png diff --git a/mods/mana/API.md b/mods/mana/API.md new file mode 100644 index 00000000..c82eda1d --- /dev/null +++ b/mods/mana/API.md @@ -0,0 +1,120 @@ +API documentation for Mana 1.0.1 +================================ + +## Introduction +The API of the Mana mod allows you to set and receive +the current and maxiumum mana reserves of a player, +and to subtract and add mana. + +## The basic rules +For integrity reasons, this mod will ensure that the following assumptions +are true at all times for all players: + +* Current and maximum mana can never be smaller than 0 +* The current value must not be greater than the maximum value +* Only integer numbers are permitted for mana values + +It should be not possible to break these rules using this API alone. +If you somehow manage to break one ofthe rules, please report a bug. + +If a real number is used as input for a value, it will be rounded +(“round up half” rule). + +## Functions +Of not specified otherwise, all functions return `nil`. +`playername` always refers to the name of a player, as string. +`value` always refers to a number and for most functions it must always be equal to or greater than 0. + + +### `mana.set(playername, value)` +Sets the mana reserve of the specified player to `value`. +If `value` is smaller than 0, the mana will be set to 0. +If `value` is greater than the maximum, the mana will be set to the maximum. + + +### `mana.setmax(playername, value)` +Sets the maximum of the player to `value`. + +If the new maximum would become smaller than the current value, +the current value will automatically be set to +the new maximum. + +### `mana.setregen(playername, value)` +Sets the mana regeneration per mana tick of the player to `value`. +Negative values are not permitted. +The length of one “mana tick” is specified as the server-wide setting +`mana_default_regen` in seconds. + + +### `mana.get(playername)` +Returns the current mana of the specified player as number. + + +### `mana.getmax(playername)` +Returns the current maximum mana of the specified player as number. + + +### `mana.getregen(playername)` +Returns the current mana regneration per mana tick of the specified +player as number. +The length of one “mana tick” is specified as the server-wide setting +`mana_default_regen` in seconds. + + +### `mana.add(playername, value)` +Adds the specified non-negative amount of mana to the player, but only +if the sum would not be greater than the maximum, + +#### Return value +* `true` on success, all mana has been added +* `false` on failure, no mana has been added + + +### `mana.subtract(playername, value)` +Subtracts the specified non-negative amount of mana from the player, +but only if the player has sufficient mana reservers. + +#### Return value +* `true` on success, all mana has been subtracted +* `false` on failure, no mana has been subtraceed + + +### `mana.add_up_to(playername, value)` +Adds the specified non-negative amount of mana to the player, but it will +be capped at the maximum. + +#### Return value +* `true, excess` on success, where `excess` is the amount of Mana which could not be added because it would have exceeded the maximum. `excess` equals `0` if all mana has been added +* `false` on failure (mana could not be added) + + +### `mana.subtract_up_to(playername, value)` +Subtracts the specified non-negative amount of mana from the player, +but if the difference is smaller than 0, the mana will be set to 0. + +#### Return value +* `true, missing` on success, where `missing` is the amount of Mana which could not be subtracted because it would have exceeded 0. `missing` equals `0` if all mana has been subtracted +* `false` on failure (mana could not be subtracted) + + +## Appendix +### General recommendations +If you want your mod to be portable, it is recommended that you balance your mod in such a way that it assumes +that every player starts with the following default mana values: + +* Max. mana: 200 +* Mana regeneration: 1 mana every 0.2 seconds + +Also assume that the max. mana never changes. +This should (hopefully) ensure that multiple independent mana-using mods are more or less balanced when using +the default settings. + +Also, to make life easier for subgame makers, define custom minetest.conf settings for your mod in order to +overwrite the mana costs (and other relevant values) used by your mod. That way, subgame makers only have to edit +minetest.conf, and not your mod. + +You do not have to bother about default values if you want to directly integrate your mod in a subgame and do +not plan to release the mod independently. + +The best way to reliable balance the mana values used by several mods is to create a standalone subgame. It is +highly recommended that you tweak the mana values of the mods to fit the subgame's needs. diff --git a/mods/mana/README.txt b/mods/mana/README.txt new file mode 100644 index 00000000..8f9ba0ce --- /dev/null +++ b/mods/mana/README.txt @@ -0,0 +1,51 @@ +Mana mod [mana] +=============== +Version: 1.0.1 +Note: This mod uses semantic versioning, as defined by version 2.0.0 of the SemVer standard. +See: + +Description +=========== +This mod adds basic support for mana to Minetest. + +Each player will have an additional attribute: Mana. To be precise: + +- Current mana reserves: How much mana the player currently has +- Maximum possible mana: How much mana the player can have at maximum +- Mana regeneration amont: How much mana will be generated each “mana tick” (default 0.2 seconds) + +By default, each player spawns with 0/200 mana, and regenerates 1 mana per fifth of a second. All +these values can be configured with the server settings (`minetest.conf`) and it is highly advised to do +so if you plan to integrate this mod into a subgame. + +The mana regeneration rate (the “mana tick”) is a global setting and is *not* configured on a +per-player basis. + +The mod provides a simple API to set, get, add and subtract the mana (and maximum) mana of any player, and +for setting the regeneration amount. Note that this mod itself does *not* change the gameplay in a meaningful +way. You should install other mods which use the Mana mod as a dependency. + +The API documentation is in the file API.md. + +If the mod “HUD bars” [hudbars] is installed, a blue bar will be added to the HUD showing the player's mana reserves. +It currently only works with version 0.3.0 of this mod. + +Otherwise, the mana is just shown as text. + +Configuration +============= + +This mod can be configured with minetest.conf! The following settings are accepted: + +* `mana_default_max`: Initial max. mana given to new players. Default: `200`. This value must be non-negative. +* `mana_default_regen`: Initial regenerated mana per “mana tick”. Default: `1`. This value must be non-negative. +* `mana_regen_timer`: The length of a “mana tick” in seconds. Each player will get his/her mana increased by the current + regen value per mana tick. Default: `0.2`. This value must be positive, also try to avoid very small values + as those could probably stress your machine a lot. + + +License information +=================== +* textures/mana_icon.png: CC-BY by Buch . +* textures/mana_bar.png: WTFPL by Wuzzy. +* Everything else: WTFPL. diff --git a/mods/mana/depends.txt b/mods/mana/depends.txt new file mode 100644 index 00000000..3e1d5c20 --- /dev/null +++ b/mods/mana/depends.txt @@ -0,0 +1 @@ +hudbars? diff --git a/mods/mana/description.txt b/mods/mana/description.txt new file mode 100644 index 00000000..e9efb088 --- /dev/null +++ b/mods/mana/description.txt @@ -0,0 +1 @@ +Adds a mana attribute to players, can be used as energy source for magical items, etc. diff --git a/mods/mana/init.lua b/mods/mana/init.lua new file mode 100644 index 00000000..dbadb4cc --- /dev/null +++ b/mods/mana/init.lua @@ -0,0 +1,308 @@ +--[[ +Mana 1.0.1 +This mod adds mana to players, a special attribute + +License: WTFPL +]] + +--[===[ + Initialization +]===] + +mana = {} +mana.playerlist = {} + +mana.settings = {} +mana.settings.default_max = 200 +mana.settings.default_regen = 1 +mana.settings.regen_timer = 0.2 + +do + local default_max = tonumber(minetest.setting_get("mana_default_max")) + if default_max ~= nil then + mana.settings.default_max = default_max + end + + local default_regen = tonumber(minetest.setting_get("mana_default_regen")) + if default_regen ~= nil then + mana.settings.default_regen = default_regen + end + + local regen_timer = tonumber(minetest.setting_get("mana_regen_timer")) + if regen_timer ~= nil then + mana.settings.regen_timer = regen_timer + end +end + + +--[===[ + API functions +]===] + +function mana.set(playername, value) + if value < 0 then + minetest.log("info", "[mana] Warning: mana.set was called with negative value!") + value = 0 + end + value = mana.round(value) + 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 + +function mana.setmax(playername, value) + if value < 0 then + value = 0 + minetest.log("info", "[mana] Warning: mana.setmax was called with negative value!") + end + value = mana.round(value) + 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 + +function mana.setregen(playername, value) + if value < 0 then + value = 0 + minetest.log("info", "[mana] Warning: mana.setregen was called with negative value!") + end + value = mana.round(value) + mana.playerlist[playername].regen = value +end + +function mana.get(playername) + return mana.playerlist[playername].mana +end + +function mana.getmax(playername) + return mana.playerlist[playername].maxmana +end + +function mana.getregen(playername) + return mana.playerlist[playername].regen +end + +function mana.add_up_to(playername, value) + local t = mana.playerlist[playername] + value = mana.round(value) + 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 + +function mana.add(playername, value) + local t = mana.playerlist[playername] + value = mana.round(value) + 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 + +function mana.subtract(playername, value) + local t = mana.playerlist[playername] + value = mana.round(value) + 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 + +function mana.subtract_up_to(playername, value) + local t = mana.playerlist[playername] + value = mana.round(value) + 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_respawnplayer(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 = mana.settings.default_max + mana.playerlist[playername].regen = mana.settings.default_regen + end + + if minetest.get_modpath("hudbars") ~= nil then + hb.init_hudbar(player, "mana", mana.get(playername), mana.getmax(playername)) + else + mana.hud_add(playername) + end +end) + + +--[===[ + Mana regeneration +]===] + +mana.regen_timer = 0 + +minetest.register_globalstep(function(dtime) + mana.regen_timer = mana.regen_timer + dtime + if mana.regen_timer >= mana.settings.regen_timer then + local factor = math.floor(mana.regen_timer / mana.settings.regen_timer) + local players = minetest.get_connected_players() + for i=1, #players do + local name = players[i]:get_player_name() + if mana.playerlist[name] ~= nil then + if players[i]:get_hp() > 0 then + mana.add_up_to(name, mana.playerlist[name].regen * factor) + end + end + end + mana.regen_timer = mana.regen_timer % mana.settings.regen_timer + end +end) + +--[===[ + HUD functions +]===] + +if minetest.get_modpath("hudbars") ~= nil then + hb.register_hudbar("mana", 0xFFFFFF, "Mana", { bar = "mana_bar.png", icon = "mana_icon.png" }, 0, mana.settings.default_max, false) + + function mana.hud_update(playername) + local player = minetest.get_player_by_name(playername) + if player ~= nil then + hb.change_hudbar(player, "mana", mana.get(playername), mana.getmax(playername)) + end + 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) + local 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 = 6.96, y = -14}, + 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 + +--[===[ + Helper functions +]===] +mana.round = function(x) + return math.ceil(math.floor(x+0.5)) +end diff --git a/mods/mana/textures/mana_bar.png b/mods/mana/textures/mana_bar.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4faa333583b1402859ebb6b053e3df349791ab GIT binary patch literal 80 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