Chat - TDMP-Team/TDMP-Lua-Modding-API GitHub Wiki
Getting started
In TDMP 0.4.0 with new chat by Danyadd you can bring some of additional features and also replace built-in chat with your own.
To get ready to work with TDMP's built-in chat, be sure to include this file:
#include "tdmp/chat.lua"
Chat functions
TDMP_AddChatMessage
TDMP_AddChatMessage(...)
Locally adds message to a chatbox. Takes infinite amount of arguments which can be:
tableColor - Sets a color for all following strings. Must be rgb array:[1,1,1]where first element is red channel, second is green and third is blue.Playerplayer - You can pass player's table or metatable to a message to make chat automatically convert it to player's name. Some modded chats may also use it for their purposes. NOTE: Player table/metatable being converted into small table which contains only steamId and playerId of a player:
-- code snipper from tdmp/chat.lua
function TDMP_AddChatMessage(...)
local args = {...}
for i, v in ipairs(args) do
local t = type(v)
if t == "table" then
if v.steamid then -- making player table smaller
v = {steamid = v.steamid, id = v.id}
-- ...
stringanytext - just a regular text which would be passed to chatbox.
Example of usage:
-- prints in chat our current health
#include "tdmp/chat.lua"
local white, red, green = {1, 1, 1}, {1, 0, 0}, {0, 1, 0}
function tick()
if InputPressed("i") then
local lPly = Player(TDMP_LocalSteamID)
local hp = math.ceil(lPly:Health()*100)
TDMP_AddChatMessage(lPly:GetColor(true), lPly:Nick() .. ", ", white, "your health is ", hp < 25 and red or green, hp)
end
end
TDMP_SendChatMessage
TDMP_SendChatMessage(string message)
Sends a message into text chat from local player. In other words, makes local player say something in text chat
stringmessage - Message to be sent
TDMP_BroadcastChatMessage
TDMP_BroadcastChatMessage(...)
Server only. Same as TDMP_AddChatMessage but broadcasts message to all players. It is recommended to keep it as short as possible.
TDMP_SendChatMessageToPlayer
TDMP_SendChatMessageToPlayer(string steamid | table receivers, ...)
Server only. Same as TDMP_AddChatMessage but sends message to specified player or players, if first argument is a table of steamIds. It is recommended to keep it as short as possible. You can find example of usage in chat hooks section
Chat hooks
TDMP's chat (no matter are you using modded or built-in one) provides three hooks for modding chat
TDMP_ChatAddMessage
Calls when message adds to a chatbox. Pushes json table of arguments which were passed to TDMP_AddChatMessage or TDMP_BroadcastChatMessage or TDMP_SendChatMessageToPlayer. Can be used for replacing default chatbox with your own (see "Replacing built-in chat" section)
TDMP_ChatSuppressMessage (Server only)
Calls when server has received chat message from a player and allows to suppress that message or replace it with our own. Mostly can be used for chat commands.
[1]string= message which player has sent[2]string= steamid of a player who sent the message By returning empty string ("") in this hook you'll completely suppress message. Otherwise, if you'll return a string, previous message would be replaced by returned one.
Example:
-- adds "!me" and "test" chat commands.
#include "tdmp/hooks.lua"
#include "tmdp/chat.lua"
#include "tmdp/player.lua"
Hook_AddListener("TDMP_ChatSuppressMessage", "TDMP_ChatCommandExample", function(msgData)
msgData = json.decode(msgData)
local msg = msgData[1]
if msg:sub(1, 3) == "!me" then
local ply = Player(msgData[2])
TDMP_BroadcastChatMessage(ply:GetColor(true), ply.nick .. " " .. msg:sub(4, #msg))
return ""
elseif msg == "test" then
local ply = Player(msgData[2])
TDMP_BroadcastChatMessage(ply:GetColor(true), ply.nick .. " ", white, "just called an ", {.5,0,1}, "event ", white, "for ", {0.2,1,.2}, "each ", white, "player!")
end
end)
TDMP_CanSeeChatMessage (Server only)
Calls after TDMP_ChatSuppressMessage hook if it did not return an empty string. Allows to make certain player not see a message from speaker.
[1]string= steamid of a player who sent the message (speaker)[2]string= steamid of a listener. Can be speaker too.[3]string= original message that speaker has sent, i.e. message which was not edited byTDMP_ChatSuppressMessagehook (if it ever was).
Example:
-- adds proximity text chat and global chat command
#include "tdmp/hooks.lua"
#include "tmdp/chat.lua"
#include "tmdp/player.lua"
Hook_AddListener("TDMP_ChatSuppressMessage", "GlobalChatCommand", function(msgData)
msgData = json.decode(msgData)
local msg = msgData[1]
if msg:sub(1,2) == "!!" then
local ply = Player(msgData[2])
TDMP_BroadcastChatMessage({.5, .5, .5}, "(Global) ", ply:GetColor(true), ply:Nick(), white, ": " .. msg:sub(3, #msg))
return ""
end
end)
Hook_AddListener("TDMP_CanSeeChatMessage", "ProximityTextChat", function(msgData)
msgData = json.decode(msgData)
local speaker = Player(msgData[1])
local listener = Player(msgData[2])
local msg = msgData[3]
if msg:sub(1,2) == "!w" then
if Distance(speaker:GetPos(), listener:GetPos()) > 4 then return "0" end
TDMP_SendChatMessageToPlayer(listener:SteamID(), {.5, .5, .5}, "(whispers) ", speaker:GetColor(true), speaker:Nick() .. " ", white, msg:sub(3, #msg))
return "0"
else
if Distance(speaker:GetPos(), listener:GetPos()) > 10^2 then
return "0"
end
end
end)
Replacing built-in chat
To replace built-in chat you must call SetBool("tdmp.disablechat", true) in init() function or outside it.
After that you'll have to handle incoming chat messages (from players and regular messages) by replacing TDMP_ChatAddMessage hook with your own.
Hook_AddListener("TDMP_ChatAddMessage", "TDMP_DefaultChatAddMessage", function(msg)
msg = json.decode(msg)
end)
As example of chatbox you can use built-in chatbox source code, which can be accessed in Teardown/data/tdmp/TDMP/chat.lua, or at GitHub page
Note that TDMP_ChatAddMessage pushes table of colors, strings and players tables which you'll have to handle. Quick example from built-in chat:
Hook_AddListener("TDMP_ChatAddMessage", "TDMP_DefaultChatAddMessage", function(msg)
msg = json.decode(msg)
-- final message which would be added to messages table.
local message = {
body = {}, -- here we'll store our message
-- and here's just custom data
lifeTime = chat.msgLifeTime,
alpha = 1
}
for i, v in ipairs(msg) do
local t = type(v)
if t == "table" and v[1] then -- if is a color
message.body[#message.body + 1] = { -- then convert it to a bit more readable table and push it to body of a message
r = v[1],
g = v[2],
b = v[3]
}
else
if t == "table" and v.id then -- otherwise if table and contains "id" field, what indicates that it's a player table
message.body[#message.body + 1] = TDMP_GetPlayer(v.id).nick -- then push player's nickname to body of a message
else
message.body[#message.body + 1] = tostring(v) -- otherwise convert value to a string and push
end
end
end
messageList[#messageList + 1] = message -- finally simply add message to messages list
if #messageList > 8 then
scrollYMax = scrollYMax + 1
end
scrollY = scrollYMax
end)
And one more snippet from built-in chat to show how to handle colors:
for i, msgData in ipairs(messageList) do
if IsShowed then
msgData.lifeTime = chat.msgLifeTime
msgData.alpha = 1.0
end
UiTextShadow(0, 0, 0, .3*msgData.alpha, 2)
UiTranslate(8,hLetter) -- moves message down by text height
local totalW, totalH = 0, 0 -- totalH is unused for now
for i, msg in ipairs(msgData.body) do
if type(msg) == "table" then -- if element is a table, then it's a color which we need to apply down below
UiColor(msg.r, msg.g, msg.b, msgData.alpha)
else -- otherwise we need to render the text
local w = UiGetTextSize(msg)
if msg:sub(#msg,#msg) ~= " " then
w = w - 7 -- dumb workaround of extra space which game adds by itself in UiGetTextSize function.
end
UiText(msg)
UiTranslate(w,0) -- Render text and offset by rendered size
totalW = totalW + w -- and add rendered size to total width of message
end
end
-- reset everything
UiTranslate(-totalW - 8,0)
UiColor(1,1,1,1)
end