Add Central Message mod

pull/37/head
Brandon 2016-05-20 22:47:12 -05:00
parent c75e110d82
commit d81f7076bd
4 changed files with 168 additions and 0 deletions

View File

@ -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`.

View File

View File

@ -0,0 +1 @@
Simple API to show messages to the center of the screen to players.

View File

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