From d81f7076bdf328988075a4ce34282ef90be635fd Mon Sep 17 00:00:00 2001 From: Brandon Date: Fri, 20 May 2016 22:47:12 -0500 Subject: [PATCH] Add Central Message mod --- mods/central_message/README.md | 53 +++++++++++++ mods/central_message/depends.txt | 0 mods/central_message/description.txt | 1 + mods/central_message/init.lua | 114 +++++++++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 mods/central_message/README.md create mode 100644 mods/central_message/depends.txt create mode 100644 mods/central_message/description.txt create mode 100644 mods/central_message/init.lua diff --git a/mods/central_message/README.md b/mods/central_message/README.md new file mode 100644 index 0000000..f4fc0d6 --- /dev/null +++ b/mods/central_message/README.md @@ -0,0 +1,53 @@ +# Central Message +## Overview +* Description: Simple API to display short messages at the center of the screen +* Author: Wuzzy +* License of everything: WTFPL +* Shortname: `central_message` +* Version: 0.2.0 (using Semantic Versioning 2.0.0, see [SemVer](http://semver.org/)) + +## Longer description +This Minetest mod allows other mods to display a short message at the center of the screen. +Each message is displayed for 5 seconds, then it is removed. +When multiple messages are pushed quickly in succession, the messages will be “stacked” +on the screen. + +This mod can be useful to inform about all sorts of events and is an alternative to use the chat log +to display special events. + +Some usage examples: +* Messages about game events, like victory, defeat, next round starting, etc. +* Error message directed to a single player +* Informational messages +* Administational messages to warn players about a coming server shutdown + +## Settings +This mod can be configured via `minetest.conf`. + +Currently, these settings are recognized: + +* `central_message_max`: Limit the number of messages displayed at once, by providing a number. Use `inf` here for no limit. Default: 7 +* `central_message_color`: Set the message color of all messages. Value must be `ColorString` (see `lua_api.txt`). Default: `0xFFFFFF` (white) + + +## API +### `cmsg.push_message_player(player, message)` +Display a new message to one player only. + +#### Parameters +* `player`: An `ObjectRef` to the player to which to send the message +* `message`: A `string` containing the message to be displayed to the player + +#### Return value +Always `nil`. + + +### `cmsg.push_message_all(message)` +Display a new message to all connected players. + +#### Parameters +* `player`: An `ObjectRef` to the player to which to send the message +* `message`: A `string` containing the message to be displayed to all players + +#### Return value +Always `nil`. diff --git a/mods/central_message/depends.txt b/mods/central_message/depends.txt new file mode 100644 index 0000000..e69de29 diff --git a/mods/central_message/description.txt b/mods/central_message/description.txt new file mode 100644 index 0000000..4a6c5db --- /dev/null +++ b/mods/central_message/description.txt @@ -0,0 +1 @@ +Simple API to show messages to the center of the screen to players. diff --git a/mods/central_message/init.lua b/mods/central_message/init.lua new file mode 100644 index 0000000..651b675 --- /dev/null +++ b/mods/central_message/init.lua @@ -0,0 +1,114 @@ +cmsg = {} +cmsg.hudids = {} +cmsg.messages = {} +cmsg.settings = {} +cmsg.next_msgids = {} + +cmsg.settings.max_messages = 7 +local setting = minetest.setting_get("central_message_max") +if type(tonumber(setting)) == "number" then + cmsg.settings.max_messages = tonumber(setting) +elseif setting == "inf" then + cmsg.settings.max_messages = nil +end + +cmsg.settings.color = 0xFFFFFF +setting = minetest.setting_get("central_message_color") +if type(tonumber(setting)) == "number" then + cmsg.settings.color = tonumber(setting) +end + +local function update_display(player, pname) + local messages = {} + local start, stop + stop = #cmsg.messages[pname] + if cmsg.settings.max_messages ~= nil then + local max = math.min(cmsg.settings.max_messages, #cmsg.messages[pname]) + if #cmsg.messages[pname] > cmsg.settings.max_messages then + start = stop - max + else + start = 1 + end + else + start = 1 + end + for i=start, stop do + table.insert(messages, cmsg.messages[pname][i].text) + end + local concat = table.concat(messages, "\n") + player:hud_change(cmsg.hudids[pname], "text", concat) +end + +cmsg.push_message_player = function(player, text) + local function push(tbl) + -- Horrible Workaround code starts here + if not (cmsg.last_push < cmsg.steps) then + minetest.after(0, push, tbl) + return + end + + local player = tbl.player + local text = tbl.text + -- Horrible Workaround code ends here + + local pname = player:get_player_name() + if cmsg.hudids[pname] == nil then + cmsg.hudids[pname] = player:hud_add({ + hud_elem_type = "text", + text = text, + number = cmsg.settings.color, + position = {x=0.5, y=0.5}, + offset = {x=-0,y=-256}, + direction = 3, + alignment = {x=0,y=1}, + scale = {x=800,y=20*cmsg.settings.max_messages}, + }) + cmsg.messages[pname] = {} + cmsg.next_msgids[pname] = 0 + table.insert(cmsg.messages[pname], {text=text, msgid=cmsg.next_msgids[pname]}) + else + cmsg.next_msgids[pname] = cmsg.next_msgids[pname] + 1 + table.insert(cmsg.messages[pname], {text=text, msgid=cmsg.next_msgids[pname]}) + update_display(player, pname) + end + + minetest.after(8, function(param) + local pname = param.player:get_player_name() + for i=1, #cmsg.messages[pname] do + if param.msgid == cmsg.messages[pname][i].msgid then + table.remove(cmsg.messages[pname], i) + break + end + end + update_display(player, pname) + end, {player=player, msgid=cmsg.next_msgids[pname]}) + + -- Update timer for Horrible Workaround + cmsg.last_push = cmsg.steps + end + + if cmsg.last_push < cmsg.steps then + push({player=player, text=text}) + else + minetest.after(0, push, {player=player, text=text}) + end +end + +cmsg.push_message_all = function(text) + local players = minetest.get_connected_players() + for i=1,#players do + cmsg.push_message_player(players[i], text) + end +end + +minetest.register_on_leaveplayer(function(player) + cmsg.hudids[player:get_player_name()] = nil +end) + +-- Horrible Workaround code starts here +cmsg.steps = 0 +cmsg.last_push = -1 +minetest.register_globalstep(function(dtime) + cmsg.steps = cmsg.steps + 1 +end) +-- Horrible Workaround code ends here