mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
Merge #3113
3113: Visual Chat Update r=def- a=Banana090 https://github.com/ddnet/ddnet/pull/3093 Co-authored-by: Дядя Женя <spy090@yandex.ru>
This commit is contained in:
commit
e5870ab06f
|
@ -3612,6 +3612,20 @@ void CCommandProcessorFragment_OpenGL3_3::Cmd_RenderQuadContainerAsSprite(const
|
|||
UseProgram(m_pSpriteProgram);
|
||||
SetState(pCommand->m_State, m_pSpriteProgram);
|
||||
|
||||
if(pCommand->m_State.m_Texture < 0)
|
||||
{
|
||||
if(m_UseMultipleTextureUnits && m_pSpriteProgram->m_LastTextureSampler >= 0)
|
||||
{
|
||||
m_TextureSlotBoundToUnit[m_pSpriteProgram->m_LastTextureSampler].m_TextureSlot = -1;
|
||||
}
|
||||
m_TextureSlotBoundToUnit[0].m_TextureSlot = -1;
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
m_pSpriteProgram->SetUniform(m_pSpriteProgram->m_LocTextureSampler, 0);
|
||||
m_pSpriteProgram->m_LastTextureSampler = -1;
|
||||
glBindSampler(0, 0);
|
||||
}
|
||||
|
||||
if(pCommand->m_Rotation != 0.0f && (m_pSpriteProgram->m_LastCenter[0] != pCommand->m_Center.x || m_pSpriteProgram->m_LastCenter[1] != pCommand->m_Center.y))
|
||||
{
|
||||
m_pSpriteProgram->SetUniformVec2(m_pSpriteProgram->m_LocCenter, 1, (float *)&pCommand->m_Center);
|
||||
|
|
|
@ -1444,13 +1444,16 @@ void CGraphics_Threaded::RenderQuadContainer(int ContainerIndex, int QuadOffset,
|
|||
WrapNormal();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX, float ScaleY)
|
||||
void CGraphics_Threaded::RenderQuadContainerEx(int ContainerIndex, int QuadOffset, int QuadDrawNum, float X, float Y, float ScaleX, float ScaleY)
|
||||
{
|
||||
SQuadContainer &Container = m_QuadContainers[ContainerIndex];
|
||||
|
||||
if((int)Container.m_Quads.size() < QuadOffset + 1)
|
||||
return;
|
||||
|
||||
if(QuadDrawNum == -1)
|
||||
QuadDrawNum = (int)Container.m_Quads.size() - QuadOffset;
|
||||
|
||||
if(IsQuadContainerBufferingEnabled())
|
||||
{
|
||||
if(Container.m_QuadBufferContainerIndex == -1)
|
||||
|
@ -1467,7 +1470,7 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
|
|||
Cmd.m_State = m_State;
|
||||
MapScreen(ScreenX0, ScreenY0, ScreenX1, ScreenY1);
|
||||
|
||||
Cmd.m_DrawNum = 1 * 6;
|
||||
Cmd.m_DrawNum = QuadDrawNum * 6;
|
||||
Cmd.m_pOffset = (void *)(QuadOffset * 6 * sizeof(unsigned int));
|
||||
Cmd.m_BufferContainerIndex = Container.m_QuadBufferContainerIndex;
|
||||
|
||||
|
@ -1499,72 +1502,70 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
|
|||
{
|
||||
if(g_Config.m_GfxQuadAsTriangle)
|
||||
{
|
||||
SQuadContainer::SQuad &Quad = Container.m_Quads[QuadOffset];
|
||||
m_aVertices[0] = Quad.m_aVertices[0];
|
||||
m_aVertices[1] = Quad.m_aVertices[1];
|
||||
m_aVertices[2] = Quad.m_aVertices[2];
|
||||
m_aVertices[3] = Quad.m_aVertices[0];
|
||||
m_aVertices[4] = Quad.m_aVertices[2];
|
||||
m_aVertices[5] = Quad.m_aVertices[3];
|
||||
|
||||
for(int i = 0; i < 6; ++i)
|
||||
for(int i = 0; i < QuadDrawNum; ++i)
|
||||
{
|
||||
m_aVertices[i].m_Pos.x *= ScaleX;
|
||||
m_aVertices[i].m_Pos.y *= ScaleY;
|
||||
SQuadContainer::SQuad &Quad = Container.m_Quads[QuadOffset + i];
|
||||
m_aVertices[i * 6 + 0] = Quad.m_aVertices[0];
|
||||
m_aVertices[i * 6 + 1] = Quad.m_aVertices[1];
|
||||
m_aVertices[i * 6 + 2] = Quad.m_aVertices[2];
|
||||
m_aVertices[i * 6 + 3] = Quad.m_aVertices[0];
|
||||
m_aVertices[i * 6 + 4] = Quad.m_aVertices[2];
|
||||
m_aVertices[i * 6 + 5] = Quad.m_aVertices[3];
|
||||
|
||||
for(int n = 0; n < 6; ++n)
|
||||
{
|
||||
m_aVertices[i * 6 + n].m_Pos.x *= ScaleX;
|
||||
m_aVertices[i * 6 + n].m_Pos.y *= ScaleY;
|
||||
|
||||
SetColor(&m_aVertices[i * 6 + n], 0);
|
||||
}
|
||||
|
||||
if(m_Rotation != 0)
|
||||
{
|
||||
CCommandBuffer::SPoint Center;
|
||||
Center.x = m_aVertices[i * 6 + 0].m_Pos.x + (m_aVertices[i * 6 + 1].m_Pos.x - m_aVertices[i * 6 + 0].m_Pos.x) / 2.f;
|
||||
Center.y = m_aVertices[i * 6 + 0].m_Pos.y + (m_aVertices[i * 6 + 2].m_Pos.y - m_aVertices[i * 6 + 0].m_Pos.y) / 2.f;
|
||||
|
||||
Rotate(Center, &m_aVertices[i * 6 + 0], 6);
|
||||
}
|
||||
|
||||
for(int n = 0; n < 6; ++n)
|
||||
{
|
||||
m_aVertices[i * 6 + n].m_Pos.x += X;
|
||||
m_aVertices[i * 6 + n].m_Pos.y += Y;
|
||||
}
|
||||
m_NumVertices += 6;
|
||||
}
|
||||
|
||||
SetColor(&m_aVertices[0], 0);
|
||||
SetColor(&m_aVertices[1], 0);
|
||||
SetColor(&m_aVertices[2], 0);
|
||||
SetColor(&m_aVertices[3], 0);
|
||||
SetColor(&m_aVertices[4], 0);
|
||||
SetColor(&m_aVertices[5], 0);
|
||||
|
||||
if(m_Rotation != 0)
|
||||
{
|
||||
CCommandBuffer::SPoint Center;
|
||||
Center.x = m_aVertices[0].m_Pos.x + (m_aVertices[1].m_Pos.x - m_aVertices[0].m_Pos.x) / 2.f;
|
||||
Center.y = m_aVertices[0].m_Pos.y + (m_aVertices[2].m_Pos.y - m_aVertices[0].m_Pos.y) / 2.f;
|
||||
|
||||
Rotate(Center, &m_aVertices[0], 6);
|
||||
}
|
||||
|
||||
for(int i = 0; i < 6; ++i)
|
||||
{
|
||||
m_aVertices[i].m_Pos.x += X;
|
||||
m_aVertices[i].m_Pos.y += Y;
|
||||
}
|
||||
m_NumVertices += 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
mem_copy(m_aVertices, &Container.m_Quads[QuadOffset], sizeof(CCommandBuffer::SVertex) * 4 * 1);
|
||||
SetColor(&m_aVertices[0], 0);
|
||||
SetColor(&m_aVertices[1], 0);
|
||||
SetColor(&m_aVertices[2], 0);
|
||||
SetColor(&m_aVertices[3], 0);
|
||||
|
||||
for(int i = 0; i < 4; ++i)
|
||||
for(int i = 0; i < QuadDrawNum; ++i)
|
||||
{
|
||||
m_aVertices[i].m_Pos.x *= ScaleX;
|
||||
m_aVertices[i].m_Pos.y *= ScaleY;
|
||||
}
|
||||
mem_copy(m_aVertices, &Container.m_Quads[QuadOffset], sizeof(CCommandBuffer::SVertex) * 4 * 1);
|
||||
|
||||
if(m_Rotation != 0)
|
||||
{
|
||||
CCommandBuffer::SPoint Center;
|
||||
Center.x = m_aVertices[0].m_Pos.x + (m_aVertices[1].m_Pos.x - m_aVertices[0].m_Pos.x) / 2.f;
|
||||
Center.y = m_aVertices[0].m_Pos.y + (m_aVertices[2].m_Pos.y - m_aVertices[0].m_Pos.y) / 2.f;
|
||||
for(int n = 0; n < 4; ++n)
|
||||
{
|
||||
m_aVertices[i * 4 + n].m_Pos.x *= ScaleX;
|
||||
m_aVertices[i * 4 + n].m_Pos.y *= ScaleY;
|
||||
SetColor(&m_aVertices[i * 4 + n], 0);
|
||||
}
|
||||
|
||||
Rotate(Center, &m_aVertices[0], 4);
|
||||
}
|
||||
if(m_Rotation != 0)
|
||||
{
|
||||
CCommandBuffer::SPoint Center;
|
||||
Center.x = m_aVertices[i * 4 + 0].m_Pos.x + (m_aVertices[i * 4 + 1].m_Pos.x - m_aVertices[i * 4 + 0].m_Pos.x) / 2.f;
|
||||
Center.y = m_aVertices[i * 4 + 0].m_Pos.y + (m_aVertices[i * 4 + 2].m_Pos.y - m_aVertices[i * 4 + 0].m_Pos.y) / 2.f;
|
||||
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
m_aVertices[i].m_Pos.x += X;
|
||||
m_aVertices[i].m_Pos.y += Y;
|
||||
Rotate(Center, &m_aVertices[i * 4 + 0], 4);
|
||||
}
|
||||
|
||||
for(int n = 0; n < 4; ++n)
|
||||
{
|
||||
m_aVertices[i * 4 + n].m_Pos.x += X;
|
||||
m_aVertices[i * 4 + n].m_Pos.y += Y;
|
||||
}
|
||||
m_NumVertices += 4;
|
||||
}
|
||||
m_NumVertices += 4;
|
||||
}
|
||||
m_Drawing = DRAWING_QUADS;
|
||||
WrapClamp();
|
||||
|
@ -1574,6 +1575,11 @@ void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int Qua
|
|||
WrapNormal();
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX, float ScaleY)
|
||||
{
|
||||
RenderQuadContainerEx(ContainerIndex, QuadOffset, 1, X, Y, ScaleX, ScaleY);
|
||||
}
|
||||
|
||||
void CGraphics_Threaded::RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo)
|
||||
{
|
||||
SQuadContainer &Container = m_QuadContainers[ContainerIndex];
|
||||
|
|
|
@ -992,6 +992,7 @@ public:
|
|||
void DeleteQuadContainer(int ContainerIndex) override;
|
||||
void RenderQuadContainer(int ContainerIndex, int QuadDrawNum) override;
|
||||
void RenderQuadContainer(int ContainerIndex, int QuadOffset, int QuadDrawNum) override;
|
||||
void RenderQuadContainerEx(int ContainerIndex, int QuadOffset, int QuadDrawNum, float X, float Y, float ScaleX = 1.f, float ScaleY = 1.f) override;
|
||||
void RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX = 1.f, float ScaleY = 1.f) override;
|
||||
void RenderQuadContainerAsSpriteMultiple(int ContainerIndex, int QuadOffset, int DrawCount, SRenderSpriteInfo *pRenderInfo) override;
|
||||
|
||||
|
|
|
@ -229,6 +229,12 @@ class CTextRender : public IEngineTextRender
|
|||
m_FirstFreeTextContainerIndex = Index;
|
||||
}
|
||||
|
||||
void FreeTextContainer(int Index)
|
||||
{
|
||||
m_TextContainers[Index].Reset();
|
||||
FreeTextContainerIndex(Index);
|
||||
}
|
||||
|
||||
STextContainer &GetTextContainer(int Index)
|
||||
{
|
||||
if(Index >= (int)m_TextContainers.size())
|
||||
|
@ -241,12 +247,6 @@ class CTextRender : public IEngineTextRender
|
|||
return m_TextContainers[Index];
|
||||
}
|
||||
|
||||
void FreeTextContainer(int Index)
|
||||
{
|
||||
m_TextContainers[Index].Reset();
|
||||
FreeTextContainerIndex(Index);
|
||||
}
|
||||
|
||||
int WordLength(const char *pText)
|
||||
{
|
||||
int Length = 0;
|
||||
|
@ -766,6 +766,13 @@ public:
|
|||
pCursor->m_GlyphCount = 0;
|
||||
pCursor->m_CharCount = 0;
|
||||
pCursor->m_MaxCharacterHeight = 0;
|
||||
pCursor->m_LongestLineWidth = 0;
|
||||
}
|
||||
|
||||
virtual void MoveCursor(CTextCursor *pCursor, float x, float y)
|
||||
{
|
||||
pCursor->m_X += x;
|
||||
pCursor->m_Y += y;
|
||||
}
|
||||
|
||||
virtual void Text(void *pFontSetV, float x, float y, float Size, const char *pText, float LineWidth)
|
||||
|
@ -1134,6 +1141,7 @@ public:
|
|||
int OldRenderFlags = m_RenderFlags;
|
||||
if(pCursor->m_LineWidth <= 0)
|
||||
SetRenderFlags(OldRenderFlags | ETextRenderFlags::TEXT_RENDER_FLAG_NO_FIRST_CHARACTER_X_BEARING | ETextRenderFlags::TEXT_RENDER_FLAG_NO_LAST_CHARACTER_ADVANCE);
|
||||
|
||||
TextContainer.m_RenderFlags = m_RenderFlags;
|
||||
SetRenderFlags(OldRenderFlags);
|
||||
|
||||
|
@ -1287,6 +1295,7 @@ public:
|
|||
|
||||
const char *pTmp = pCurrent;
|
||||
int NextCharacter = str_utf8_decode(&pTmp);
|
||||
|
||||
while(pCurrent < pBatchEnd)
|
||||
{
|
||||
TextContainer.m_CharCount += pTmp - pCurrent;
|
||||
|
@ -1401,6 +1410,9 @@ public:
|
|||
pCursor->m_GlyphCount++;
|
||||
++CharacterCounter;
|
||||
}
|
||||
|
||||
if(DrawX > pCursor->m_LongestLineWidth)
|
||||
pCursor->m_LongestLineWidth = DrawX;
|
||||
}
|
||||
|
||||
if(NewLine)
|
||||
|
|
|
@ -331,6 +331,7 @@ public:
|
|||
virtual void DeleteQuadContainer(int ContainerIndex) = 0;
|
||||
virtual void RenderQuadContainer(int ContainerIndex, int QuadDrawNum) = 0;
|
||||
virtual void RenderQuadContainer(int ContainerIndex, int QuadOffset, int QuadDrawNum) = 0;
|
||||
virtual void RenderQuadContainerEx(int ContainerIndex, int QuadOffset, int QuadDrawNum, float X, float Y, float ScaleX = 1.f, float ScaleY = 1.f) = 0;
|
||||
virtual void RenderQuadContainerAsSprite(int ContainerIndex, int QuadOffset, float X, float Y, float ScaleX = 1.f, float ScaleY = 1.f) = 0;
|
||||
|
||||
struct SRenderSpriteInfo
|
||||
|
|
|
@ -265,6 +265,9 @@ MACRO_CONFIG_INT(SvRejoinTeam0, sv_rejoin_team_0, 1, 0, 1, CFGFLAG_SERVER, "Make
|
|||
MACRO_CONFIG_INT(ClReconnectTimeout, cl_reconnect_timeout, 120, 0, 600, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How many seconds to wait before reconnecting (after timeout, 0 for off)")
|
||||
MACRO_CONFIG_INT(ClReconnectFull, cl_reconnect_full, 5, 0, 600, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How many seconds to wait before reconnecting (when server is full, 0 for off)")
|
||||
|
||||
MACRO_CONFIG_INT(ClChatTee, cl_chat_tee, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show a tee before the player name in chat");
|
||||
MACRO_CONFIG_INT(ClChatBackground, cl_chat_background, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Show a background for each chat message");
|
||||
|
||||
MACRO_CONFIG_COL(ClMessageSystemColor, cl_message_system_color, 2817983, CFGFLAG_CLIENT | CFGFLAG_SAVE, "System message color")
|
||||
MACRO_CONFIG_COL(ClMessageClientColor, cl_message_client_color, 9633471, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Client message color")
|
||||
MACRO_CONFIG_COL(ClMessageHighlightColor, cl_message_highlight_color, 65471, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Highlighted message color")
|
||||
|
|
|
@ -49,6 +49,8 @@ public:
|
|||
float m_X, m_Y;
|
||||
float m_MaxCharacterHeight;
|
||||
|
||||
float m_LongestLineWidth;
|
||||
|
||||
CFont *m_pFont;
|
||||
float m_FontSize;
|
||||
float m_AlignedFontSize;
|
||||
|
@ -78,6 +80,7 @@ class ITextRender : public IInterface
|
|||
MACRO_INTERFACE("textrender", 0)
|
||||
public:
|
||||
virtual void SetCursor(CTextCursor *pCursor, float x, float y, float FontSize, int Flags) = 0;
|
||||
virtual void MoveCursor(CTextCursor *pCursor, float x, float y) = 0;
|
||||
|
||||
virtual CFont *LoadFont(const char *pFilename, const unsigned char *pBuf, size_t Size) = 0;
|
||||
virtual bool LoadFallbackFont(CFont *pFont, const char *pFilename, const unsigned char *pBuf, size_t Size) = 0;
|
||||
|
|
|
@ -14,10 +14,12 @@
|
|||
#include <game/generated/client_data.h>
|
||||
#include <game/generated/protocol.h>
|
||||
|
||||
#include <game/client/animstate.h>
|
||||
#include <game/client/gameclient.h>
|
||||
|
||||
#include <game/client/components/console.h>
|
||||
#include <game/client/components/scoreboard.h>
|
||||
#include <game/client/components/skins.h>
|
||||
#include <game/client/components/sounds.h>
|
||||
#include <game/localization.h>
|
||||
|
||||
|
@ -29,6 +31,7 @@ CChat::CChat()
|
|||
{
|
||||
// reset the container indices, so the text containers can be deleted on reset
|
||||
m_aLines[i].m_TextContainerIndex = -1;
|
||||
m_aLines[i].m_QuadContainerIndex = -1;
|
||||
}
|
||||
|
||||
#define CHAT_COMMAND(name, params, flags, callback, userdata, help) RegisterCommand(name, params, flags, help);
|
||||
|
@ -44,31 +47,43 @@ void CChat::RegisterCommand(const char *pName, const char *pParams, int flags, c
|
|||
m_Commands.add_unsorted(CCommand{pName, pParams});
|
||||
}
|
||||
|
||||
void CChat::OnWindowResize()
|
||||
void CChat::RebuildChat()
|
||||
{
|
||||
for(int i = 0; i < MAX_LINES; i++)
|
||||
{
|
||||
if(m_aLines[i].m_TextContainerIndex != -1)
|
||||
TextRender()->DeleteTextContainer(m_aLines[i].m_TextContainerIndex);
|
||||
m_aLines[i].m_TextContainerIndex = -1;
|
||||
if(m_aLines[i].m_QuadContainerIndex != -1)
|
||||
Graphics()->DeleteQuadContainer(m_aLines[i].m_QuadContainerIndex);
|
||||
m_aLines[i].m_QuadContainerIndex = -1;
|
||||
// recalculate sizes
|
||||
m_aLines[i].m_YOffset[0] = -1.f;
|
||||
m_aLines[i].m_YOffset[1] = -1.f;
|
||||
}
|
||||
}
|
||||
|
||||
void CChat::OnWindowResize()
|
||||
{
|
||||
RebuildChat();
|
||||
}
|
||||
|
||||
void CChat::Reset()
|
||||
{
|
||||
for(int i = 0; i < MAX_LINES; i++)
|
||||
{
|
||||
if(m_aLines[i].m_TextContainerIndex != -1)
|
||||
TextRender()->DeleteTextContainer(m_aLines[i].m_TextContainerIndex);
|
||||
if(m_aLines[i].m_QuadContainerIndex != -1)
|
||||
Graphics()->DeleteQuadContainer(m_aLines[i].m_QuadContainerIndex);
|
||||
m_aLines[i].m_Time = 0;
|
||||
m_aLines[i].m_aText[0] = 0;
|
||||
m_aLines[i].m_aName[0] = 0;
|
||||
m_aLines[i].m_Friend = false;
|
||||
m_aLines[i].m_TextContainerIndex = -1;
|
||||
m_aLines[i].m_QuadContainerIndex = -1;
|
||||
m_aLines[i].m_TimesRepeated = 0;
|
||||
m_aLines[i].m_HasRenderTee = false;
|
||||
}
|
||||
m_PrevScoreBoardShowed = false;
|
||||
m_PrevShowChat = false;
|
||||
|
@ -136,6 +151,18 @@ void CChat::ConEcho(IConsole::IResult *pResult, void *pUserData)
|
|||
((CChat *)pUserData)->Echo(pResult->GetString(0));
|
||||
}
|
||||
|
||||
void CChat::ConchainChatTee(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
((CChat *)pUserData)->RebuildChat();
|
||||
}
|
||||
|
||||
void CChat::ConchainChatBackground(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData)
|
||||
{
|
||||
pfnCallback(pResult, pCallbackUserData);
|
||||
((CChat *)pUserData)->RebuildChat();
|
||||
}
|
||||
|
||||
void CChat::Echo(const char *pString)
|
||||
{
|
||||
AddLine(-2, 0, pString);
|
||||
|
@ -148,6 +175,8 @@ void CChat::OnConsoleInit()
|
|||
Console()->Register("chat", "s['team'|'all'] ?r[message]", CFGFLAG_CLIENT, ConChat, this, "Enable chat with all/team mode");
|
||||
Console()->Register("+show_chat", "", CFGFLAG_CLIENT, ConShowChat, this, "Show chat");
|
||||
Console()->Register("echo", "r[message]", CFGFLAG_CLIENT, ConEcho, this, "Echo the text in chat window");
|
||||
Console()->Chain("cl_chat_tee", ConchainChatTee, this);
|
||||
Console()->Chain("cl_chat_background", ConchainChatBackground, this);
|
||||
}
|
||||
|
||||
bool CChat::OnInput(IInput::CEvent Event)
|
||||
|
@ -662,13 +691,16 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
CLine *pCurrentLine = &m_aLines[m_CurrentLine];
|
||||
|
||||
// If it's a client message, m_aText will have ": " prepended so we have to work around it.
|
||||
if(pCurrentLine->m_Team == Team && pCurrentLine->m_ClientID == ClientID &&
|
||||
((ClientID < 0 && str_comp(pCurrentLine->m_aText, pLine) == 0) || (ClientID >= 0 && str_length(pCurrentLine->m_aText) > 2 && str_comp(pCurrentLine->m_aText + 2, pLine) == 0)))
|
||||
if(pCurrentLine->m_Team == Team && pCurrentLine->m_ClientID == ClientID && str_comp(pCurrentLine->m_aText, pLine) == 0)
|
||||
{
|
||||
pCurrentLine->m_TimesRepeated++;
|
||||
if(pCurrentLine->m_TextContainerIndex != -1)
|
||||
TextRender()->DeleteTextContainer(pCurrentLine->m_TextContainerIndex);
|
||||
pCurrentLine->m_TextContainerIndex = -1;
|
||||
|
||||
if(pCurrentLine->m_QuadContainerIndex != -1)
|
||||
Graphics()->DeleteQuadContainer(pCurrentLine->m_QuadContainerIndex);
|
||||
pCurrentLine->m_QuadContainerIndex = -1;
|
||||
pCurrentLine->m_Time = time();
|
||||
pCurrentLine->m_YOffset[0] = -1.f;
|
||||
pCurrentLine->m_YOffset[1] = -1.f;
|
||||
|
@ -690,6 +722,10 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
TextRender()->DeleteTextContainer(pCurrentLine->m_TextContainerIndex);
|
||||
pCurrentLine->m_TextContainerIndex = -1;
|
||||
|
||||
if(pCurrentLine->m_QuadContainerIndex != -1)
|
||||
Graphics()->DeleteQuadContainer(pCurrentLine->m_QuadContainerIndex);
|
||||
pCurrentLine->m_QuadContainerIndex = -1;
|
||||
|
||||
// check for highlighted name
|
||||
if(Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
|
@ -751,16 +787,35 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
Highlighted = true;
|
||||
}
|
||||
else
|
||||
str_copy(pCurrentLine->m_aName, m_pClient->m_aClients[ClientID].m_aName, sizeof(pCurrentLine->m_aName));
|
||||
str_format(pCurrentLine->m_aName, sizeof(pCurrentLine->m_aName), "%s", m_pClient->m_aClients[ClientID].m_aName);
|
||||
|
||||
str_format(pCurrentLine->m_aText, sizeof(pCurrentLine->m_aText), ": %s", pLine);
|
||||
str_format(pCurrentLine->m_aText, sizeof(pCurrentLine->m_aText), "%s", pLine);
|
||||
pCurrentLine->m_Friend = m_pClient->m_aClients[ClientID].m_Friend;
|
||||
}
|
||||
|
||||
pCurrentLine->m_HasRenderTee = false;
|
||||
|
||||
pCurrentLine->m_Friend = ClientID >= 0 ? m_pClient->m_aClients[ClientID].m_Friend : false;
|
||||
|
||||
if(pCurrentLine->m_ClientID >= 0 && pCurrentLine->m_aName[0] != '\0')
|
||||
{
|
||||
if(g_Config.m_ClChatTee)
|
||||
{
|
||||
pCurrentLine->m_CustomColoredSkin = m_pClient->m_aClients[pCurrentLine->m_ClientID].m_RenderInfo.m_CustomColoredSkin;
|
||||
if(pCurrentLine->m_CustomColoredSkin)
|
||||
pCurrentLine->m_RenderSkin = m_pClient->m_aClients[pCurrentLine->m_ClientID].m_RenderInfo.m_ColorableRenderSkin;
|
||||
else
|
||||
pCurrentLine->m_RenderSkin = m_pClient->m_aClients[pCurrentLine->m_ClientID].m_RenderInfo.m_OriginalRenderSkin;
|
||||
|
||||
str_copy(pCurrentLine->m_aSkinName, m_pClient->m_aClients[pCurrentLine->m_ClientID].m_aSkinName, sizeof(pCurrentLine->m_aSkinName));
|
||||
pCurrentLine->m_ColorBody = m_pClient->m_aClients[pCurrentLine->m_ClientID].m_RenderInfo.m_ColorBody;
|
||||
pCurrentLine->m_ColorFeet = m_pClient->m_aClients[pCurrentLine->m_ClientID].m_RenderInfo.m_ColorFeet;
|
||||
pCurrentLine->m_HasRenderTee = true;
|
||||
}
|
||||
}
|
||||
|
||||
char aBuf[1024];
|
||||
str_format(aBuf, sizeof(aBuf), "%s%s", pCurrentLine->m_aName, pCurrentLine->m_aText);
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", pCurrentLine->m_aName, pCurrentLine->m_aText);
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, Team >= 2 ? "whisper" : (pCurrentLine->m_Team ? "teamchat" : "chat"), aBuf, Highlighted);
|
||||
}
|
||||
|
||||
|
@ -786,7 +841,7 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
if(Now - m_aLastSoundPlayed[CHAT_HIGHLIGHT] >= time_freq() * 3 / 10)
|
||||
{
|
||||
char aBuf[1024];
|
||||
str_format(aBuf, sizeof(aBuf), "%s%s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText);
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", m_aLines[m_CurrentLine].m_aName, m_aLines[m_CurrentLine].m_aText);
|
||||
Client()->Notify("DDNet Chat", aBuf);
|
||||
if(g_Config.m_SndHighlight)
|
||||
{
|
||||
|
@ -813,27 +868,65 @@ void CChat::AddLine(int ClientID, int Team, const char *pLine)
|
|||
}
|
||||
}
|
||||
|
||||
void CChat::RefindSkins()
|
||||
{
|
||||
for(int i = 0; i < MAX_LINES; i++)
|
||||
{
|
||||
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
continue;
|
||||
|
||||
if(m_aLines[r].m_HasRenderTee)
|
||||
{
|
||||
const CSkin *pSkin = m_pClient->m_pSkins->Get(m_pClient->m_pSkins->Find(m_aLines[r].m_aSkinName));
|
||||
if(m_aLines[r].m_CustomColoredSkin)
|
||||
m_aLines[r].m_RenderSkin = pSkin->m_ColorableSkin;
|
||||
else
|
||||
m_aLines[r].m_RenderSkin = pSkin->m_OriginalSkin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CChat::OnPrepareLines()
|
||||
{
|
||||
float x = 5.0f;
|
||||
float y = 300.0f - 28.0f;
|
||||
float FontSize = 6.0f;
|
||||
float FontSize = FONT_SIZE;
|
||||
|
||||
bool ForceRecreate = m_pClient->m_pScoreboard->Active() != m_PrevScoreBoardShowed;
|
||||
bool ShowLargeArea = m_Show || g_Config.m_ClShowChat == 2;
|
||||
|
||||
ForceRecreate |= ShowLargeArea != m_PrevShowChat;
|
||||
|
||||
m_PrevScoreBoardShowed = m_pClient->m_pScoreboard->Active();
|
||||
m_PrevShowChat = ShowLargeArea;
|
||||
|
||||
float RealMsgPaddingX = MESSAGE_PADDING_X;
|
||||
float RealMsgPaddingY = MESSAGE_PADDING_Y;
|
||||
float RealMsgPaddingTee = MESSAGE_TEE_SIZE + MESSAGE_TEE_PADDING_RIGHT;
|
||||
|
||||
if(!g_Config.m_ClChatBackground)
|
||||
{
|
||||
RealMsgPaddingX = 0;
|
||||
RealMsgPaddingY = (g_Config.m_ClChatTee ? (MESSAGE_TEE_SIZE - FONT_SIZE) : 0);
|
||||
}
|
||||
|
||||
if(!g_Config.m_ClChatTee)
|
||||
RealMsgPaddingTee = 0;
|
||||
|
||||
int64 Now = time();
|
||||
float LineWidth = m_pClient->m_pScoreboard->Active() ? 90.0f : 200.0f;
|
||||
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 230.0f : m_PrevShowChat ? 50.0f : 200.0f;
|
||||
float LineWidth = (m_pClient->m_pScoreboard->Active() ? 90.0f : 200.0f) - RealMsgPaddingX - RealMsgPaddingTee;
|
||||
|
||||
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 180.0f : m_PrevShowChat ? 50.0f : 200.0f;
|
||||
float Begin = x;
|
||||
float TextBegin = Begin + RealMsgPaddingX / 2.0f;
|
||||
CTextCursor Cursor;
|
||||
int OffsetType = m_pClient->m_pScoreboard->Active() ? 1 : 0;
|
||||
|
||||
for(int i = 0; i < MAX_LINES; i++)
|
||||
{
|
||||
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
|
||||
|
||||
if(Now > m_aLines[r].m_Time + 16 * time_freq() && !m_PrevShowChat)
|
||||
break;
|
||||
|
||||
|
@ -845,14 +938,19 @@ void CChat::OnPrepareLines()
|
|||
|
||||
m_aLines[r].m_TextContainerIndex = -1;
|
||||
|
||||
char aName[64] = "";
|
||||
if(m_aLines[r].m_QuadContainerIndex != -1)
|
||||
Graphics()->DeleteQuadContainer(m_aLines[r].m_QuadContainerIndex);
|
||||
|
||||
m_aLines[r].m_QuadContainerIndex = -1;
|
||||
|
||||
char aName[64 + 12] = "";
|
||||
|
||||
if(g_Config.m_ClShowIDs && m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
|
||||
{
|
||||
if(m_aLines[r].m_ClientID >= 10)
|
||||
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
|
||||
if(m_aLines[r].m_ClientID < 10)
|
||||
str_format(aName, sizeof(aName), " %d: ", m_aLines[r].m_ClientID);
|
||||
else
|
||||
str_format(aName, sizeof(aName), " %d: ", m_aLines[r].m_ClientID);
|
||||
str_format(aName, sizeof(aName), "%d: ", m_aLines[r].m_ClientID);
|
||||
}
|
||||
|
||||
str_append(aName, m_aLines[r].m_aName, sizeof(aName));
|
||||
|
@ -863,20 +961,38 @@ void CChat::OnPrepareLines()
|
|||
else
|
||||
str_format(aCount, sizeof(aCount), " [%d]", m_aLines[r].m_TimesRepeated + 1);
|
||||
|
||||
if(!g_Config.m_ClChatTee)
|
||||
{
|
||||
m_aLines[r].m_HasRenderTee = false;
|
||||
}
|
||||
|
||||
// get the y offset (calculate it if we haven't done that yet)
|
||||
if(m_aLines[r].m_YOffset[OffsetType] < 0.0f)
|
||||
{
|
||||
TextRender()->SetCursor(&Cursor, Begin, 0.0f, FontSize, 0);
|
||||
TextRender()->SetCursor(&Cursor, TextBegin, 0.0f, FontSize, 0);
|
||||
Cursor.m_LineWidth = LineWidth;
|
||||
|
||||
if(g_Config.m_ClMessageFriend)
|
||||
Cursor.m_X += RealMsgPaddingTee;
|
||||
|
||||
if(m_aLines[r].m_Friend && g_Config.m_ClMessageFriend)
|
||||
{
|
||||
TextRender()->TextEx(&Cursor, "♥ ", -1);
|
||||
}
|
||||
|
||||
TextRender()->TextEx(&Cursor, aName, -1);
|
||||
if(m_aLines[r].m_TimesRepeated > 0)
|
||||
TextRender()->TextEx(&Cursor, aCount, -1);
|
||||
TextRender()->TextEx(&Cursor, m_aLines[r].m_aText, -1);
|
||||
m_aLines[r].m_YOffset[OffsetType] = Cursor.m_Y + Cursor.m_FontSize;
|
||||
|
||||
TextRender()->TextEx(&Cursor, ": ", -1);
|
||||
|
||||
CTextCursor AppendCursor = Cursor;
|
||||
AppendCursor.m_StartX = Cursor.m_X;
|
||||
|
||||
TextRender()->TextEx(&AppendCursor, m_aLines[r].m_aText, -1);
|
||||
|
||||
m_aLines[r].m_YOffset[OffsetType] = AppendCursor.m_Y + AppendCursor.m_FontSize + RealMsgPaddingY;
|
||||
}
|
||||
|
||||
y -= m_aLines[r].m_YOffset[OffsetType];
|
||||
|
||||
// cut off if msgs waste too much space
|
||||
|
@ -884,51 +1000,57 @@ void CChat::OnPrepareLines()
|
|||
break;
|
||||
|
||||
// the position the text was created
|
||||
m_aLines[r].m_TextYOffset = y;
|
||||
m_aLines[r].m_TextYOffset = y + RealMsgPaddingY / 2.f;
|
||||
|
||||
// reset the cursor
|
||||
TextRender()->SetCursor(&Cursor, Begin, y, FontSize, TEXTFLAG_RENDER);
|
||||
TextRender()->SetCursor(&Cursor, TextBegin, m_aLines[r].m_TextYOffset, FontSize, TEXTFLAG_RENDER);
|
||||
Cursor.m_LineWidth = LineWidth;
|
||||
|
||||
if(g_Config.m_ClMessageFriend)
|
||||
// Message is from valid player
|
||||
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
|
||||
{
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageFriendColor));
|
||||
TextRender()->TextColor(rgb.WithAlpha(m_aLines[r].m_Friend ? 1.f : 0.f)); //Less ugly hack to align messages
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, "♥ ");
|
||||
else
|
||||
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, "♥ ");
|
||||
Cursor.m_X += RealMsgPaddingTee;
|
||||
|
||||
if(m_aLines[r].m_Friend && g_Config.m_ClMessageFriend)
|
||||
{
|
||||
const char *pHeartStr = "♥ ";
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageFriendColor));
|
||||
TextRender()->TextColor(rgb.WithAlpha(1.f));
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, pHeartStr);
|
||||
else
|
||||
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, pHeartStr);
|
||||
}
|
||||
}
|
||||
|
||||
// render name
|
||||
ColorRGBA NameColor;
|
||||
if(m_aLines[r].m_ClientID == -1) // system
|
||||
{
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageSystemColor));
|
||||
TextRender()->TextColor(rgb);
|
||||
NameColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageSystemColor));
|
||||
}
|
||||
else if(m_aLines[r].m_ClientID == -2) // client
|
||||
{
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageClientColor));
|
||||
TextRender()->TextColor(rgb);
|
||||
NameColor = color_cast<ColorRGBA>(ColorHSLA(g_Config.m_ClMessageClientColor));
|
||||
}
|
||||
else if(m_aLines[r].m_Team)
|
||||
{
|
||||
ColorRGBA rgb = CalculateNameColor(ColorHSLA(g_Config.m_ClMessageTeamColor));
|
||||
TextRender()->TextColor(rgb); // team message
|
||||
NameColor = CalculateNameColor(ColorHSLA(g_Config.m_ClMessageTeamColor));
|
||||
}
|
||||
else if(m_aLines[r].m_NameColor == TEAM_RED)
|
||||
TextRender()->TextColor(1.0f, 0.5f, 0.5f, 1.f); // red
|
||||
NameColor = ColorRGBA(1.0f, 0.5f, 0.5f, 1.f); // red
|
||||
else if(m_aLines[r].m_NameColor == TEAM_BLUE)
|
||||
TextRender()->TextColor(0.7f, 0.7f, 1.0f, 1.f); // blue
|
||||
NameColor = ColorRGBA(0.7f, 0.7f, 1.0f, 1.f); // blue
|
||||
else if(m_aLines[r].m_NameColor == TEAM_SPECTATORS)
|
||||
TextRender()->TextColor(0.75f, 0.5f, 0.75f, 1.f); // spectator
|
||||
NameColor = ColorRGBA(0.75f, 0.5f, 0.75f, 1.f); // spectator
|
||||
else if(m_aLines[r].m_ClientID >= 0 && g_Config.m_ClChatTeamColors && m_pClient->m_Teams.Team(m_aLines[r].m_ClientID))
|
||||
{
|
||||
ColorRGBA rgb = color_cast<ColorRGBA>(ColorHSLA(m_pClient->m_Teams.Team(m_aLines[r].m_ClientID) / 64.0f, 1.0f, 0.75f));
|
||||
TextRender()->TextColor(rgb);
|
||||
NameColor = color_cast<ColorRGBA>(ColorHSLA(m_pClient->m_Teams.Team(m_aLines[r].m_ClientID) / 64.0f, 1.0f, 0.75f));
|
||||
}
|
||||
else
|
||||
TextRender()->TextColor(0.8f, 0.8f, 0.8f, 1.f);
|
||||
NameColor = ColorRGBA(0.8f, 0.8f, 0.8f, 1.f);
|
||||
|
||||
TextRender()->TextColor(NameColor);
|
||||
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, aName);
|
||||
|
@ -944,6 +1066,15 @@ void CChat::OnPrepareLines()
|
|||
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, aCount);
|
||||
}
|
||||
|
||||
if(m_aLines[r].m_ClientID >= 0 && m_aLines[r].m_aName[0] != '\0')
|
||||
{
|
||||
TextRender()->TextColor(NameColor);
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, ": ");
|
||||
else
|
||||
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, ": ");
|
||||
}
|
||||
|
||||
// render line
|
||||
ColorRGBA Color;
|
||||
if(m_aLines[r].m_ClientID == -1) // system
|
||||
|
@ -959,10 +1090,20 @@ void CChat::OnPrepareLines()
|
|||
|
||||
TextRender()->TextColor(Color);
|
||||
|
||||
CTextCursor AppendCursor = Cursor;
|
||||
AppendCursor.m_StartX = Cursor.m_X;
|
||||
|
||||
if(m_aLines[r].m_TextContainerIndex == -1)
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&Cursor, m_aLines[r].m_aText);
|
||||
m_aLines[r].m_TextContainerIndex = TextRender()->CreateTextContainer(&AppendCursor, m_aLines[r].m_aText);
|
||||
else
|
||||
TextRender()->AppendTextContainer(&Cursor, m_aLines[r].m_TextContainerIndex, m_aLines[r].m_aText);
|
||||
TextRender()->AppendTextContainer(&AppendCursor, m_aLines[r].m_TextContainerIndex, m_aLines[r].m_aText);
|
||||
|
||||
if(g_Config.m_ClChatBackground && (m_aLines[r].m_aText[0] != '\0' || m_aLines[r].m_aName[0] != '\0'))
|
||||
{
|
||||
float Height = m_aLines[r].m_YOffset[OffsetType];
|
||||
Graphics()->SetColor(1, 1, 1, 1);
|
||||
m_aLines[r].m_QuadContainerIndex = RenderTools()->CreateRoundRectQuadContainer(Begin, y, AppendCursor.m_LongestLineWidth - Begin + RealMsgPaddingX, Height, RealMsgPaddingY, CUI::CORNER_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
TextRender()->TextColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
@ -1066,8 +1207,18 @@ void CChat::OnRender()
|
|||
OnPrepareLines();
|
||||
|
||||
int64 Now = time();
|
||||
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 230.0f : m_PrevShowChat ? 50.0f : 200.0f;
|
||||
float HeightLimit = m_pClient->m_pScoreboard->Active() ? 180.0f : m_PrevShowChat ? 50.0f : 200.0f;
|
||||
int OffsetType = m_pClient->m_pScoreboard->Active() ? 1 : 0;
|
||||
|
||||
float RealMsgPaddingX = MESSAGE_PADDING_X;
|
||||
float RealMsgPaddingY = MESSAGE_PADDING_Y;
|
||||
|
||||
if(!g_Config.m_ClChatBackground)
|
||||
{
|
||||
RealMsgPaddingX = 0;
|
||||
RealMsgPaddingY = (g_Config.m_ClChatTee ? (MESSAGE_TEE_SIZE - FONT_SIZE) : 0);
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_LINES; i++)
|
||||
{
|
||||
int r = ((m_CurrentLine - i) + MAX_LINES) % MAX_LINES;
|
||||
|
@ -1082,11 +1233,44 @@ void CChat::OnRender()
|
|||
|
||||
float Blend = Now > m_aLines[r].m_Time + 14 * time_freq() && !m_PrevShowChat ? 1.0f - (Now - m_aLines[r].m_Time - 14 * time_freq()) / (2.0f * time_freq()) : 1.0f;
|
||||
|
||||
// Draw backgrounds for messages in one batch
|
||||
if(g_Config.m_ClChatBackground)
|
||||
{
|
||||
Graphics()->TextureClear();
|
||||
if(m_aLines[r].m_QuadContainerIndex != -1)
|
||||
{
|
||||
Graphics()->SetColor(0, 0, 0, 0.12f * Blend);
|
||||
Graphics()->RenderQuadContainerEx(m_aLines[r].m_QuadContainerIndex, 0, -1, 0, ((y + RealMsgPaddingY / 2.0f) - m_aLines[r].m_TextYOffset));
|
||||
}
|
||||
}
|
||||
|
||||
if(m_aLines[r].m_TextContainerIndex != -1)
|
||||
{
|
||||
if(g_Config.m_ClChatTee && m_aLines[r].m_HasRenderTee)
|
||||
{
|
||||
CTeeRenderInfo RenderInfo;
|
||||
RenderInfo.m_CustomColoredSkin = m_aLines[r].m_CustomColoredSkin;
|
||||
if(m_aLines[r].m_CustomColoredSkin)
|
||||
RenderInfo.m_ColorableRenderSkin = m_aLines[r].m_RenderSkin;
|
||||
else
|
||||
RenderInfo.m_OriginalRenderSkin = m_aLines[r].m_RenderSkin;
|
||||
|
||||
RenderInfo.m_ColorBody = m_aLines[r].m_ColorBody;
|
||||
RenderInfo.m_ColorFeet = m_aLines[r].m_ColorFeet;
|
||||
RenderInfo.m_Size = MESSAGE_TEE_SIZE;
|
||||
|
||||
float RowHeight = FONT_SIZE + RealMsgPaddingY;
|
||||
float OffsetTeeY = MESSAGE_TEE_SIZE / 2.0f;
|
||||
float FullHeightMinusTee = RowHeight - MESSAGE_TEE_SIZE;
|
||||
float TWSkinUnreliableOffset = 0.5f; // teeworlds skins were always a bit in the ground
|
||||
|
||||
CAnimState *pIdleState = CAnimState::GetIdle();
|
||||
RenderTools()->RenderTee(pIdleState, &RenderInfo, EMOTE_NORMAL, vec2(1, 0.1f), vec2(x + (RealMsgPaddingX + MESSAGE_TEE_SIZE) / 2.0f, y + OffsetTeeY + FullHeightMinusTee / 2.0f + TWSkinUnreliableOffset), Blend);
|
||||
}
|
||||
|
||||
STextRenderColor TextOutline(0.f, 0.f, 0.f, 0.3f * Blend);
|
||||
STextRenderColor Text(1.f, 1.f, 1.f, Blend);
|
||||
TextRender()->RenderTextContainer(m_aLines[r].m_TextContainerIndex, &Text, &TextOutline, 0, y - m_aLines[r].m_TextYOffset);
|
||||
TextRender()->RenderTextContainer(m_aLines[r].m_TextContainerIndex, &Text, &TextOutline, 0, (y + RealMsgPaddingY / 2.0f) - m_aLines[r].m_TextYOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
#ifndef GAME_CLIENT_COMPONENTS_CHAT_H
|
||||
#define GAME_CLIENT_COMPONENTS_CHAT_H
|
||||
#include <engine/shared/config.h>
|
||||
#include <engine/shared/ringbuffer.h>
|
||||
#include <game/client/component.h>
|
||||
#include <game/client/lineinput.h>
|
||||
|
@ -10,9 +11,16 @@ class CChat : public CComponent
|
|||
{
|
||||
CLineInput m_Input;
|
||||
|
||||
static constexpr float MESSAGE_PADDING_X = 5.0f;
|
||||
static constexpr float MESSAGE_TEE_SIZE = 8.0f;
|
||||
static constexpr float MESSAGE_TEE_PADDING_RIGHT = 0.5f;
|
||||
static constexpr float FONT_SIZE = 6.0f;
|
||||
static constexpr float MESSAGE_PADDING_Y = 3.f;
|
||||
static_assert(FONT_SIZE + MESSAGE_PADDING_Y >= 8.0f, "Corners for background chat are too huge for this combination of font size and message padding.");
|
||||
|
||||
enum
|
||||
{
|
||||
MAX_LINES = 25,
|
||||
MAX_LINES = 25
|
||||
};
|
||||
|
||||
struct CLine
|
||||
|
@ -28,6 +36,15 @@ class CChat : public CComponent
|
|||
bool m_Highlighted;
|
||||
|
||||
int m_TextContainerIndex;
|
||||
int m_QuadContainerIndex;
|
||||
|
||||
char m_aSkinName[sizeof(g_Config.m_ClPlayerSkin) / sizeof(g_Config.m_ClPlayerSkin[0])];
|
||||
CSkin::SSkinTextures m_RenderSkin;
|
||||
bool m_CustomColoredSkin;
|
||||
ColorRGBA m_ColorBody;
|
||||
ColorRGBA m_ColorFeet;
|
||||
|
||||
bool m_HasRenderTee;
|
||||
float m_TextYOffset;
|
||||
|
||||
int m_TimesRepeated;
|
||||
|
@ -92,6 +109,9 @@ class CChat : public CComponent
|
|||
static void ConShowChat(IConsole::IResult *pResult, void *pUserData);
|
||||
static void ConEcho(IConsole::IResult *pResult, void *pUserData);
|
||||
|
||||
static void ConchainChatTee(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
static void ConchainChatBackground(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
|
||||
|
||||
bool LineShouldHighlight(const char *pLine, const char *pName);
|
||||
void StoreSave(const char *pText);
|
||||
void Reset();
|
||||
|
@ -112,9 +132,12 @@ public:
|
|||
virtual void OnConsoleInit();
|
||||
virtual void OnStateChange(int NewState, int OldState);
|
||||
virtual void OnRender();
|
||||
virtual void RefindSkins();
|
||||
virtual void OnPrepareLines();
|
||||
virtual void OnRelease();
|
||||
virtual void OnMessage(int MsgType, void *pRawMsg);
|
||||
virtual bool OnInput(IInput::CEvent Event);
|
||||
|
||||
void RebuildChat();
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include <game/generated/protocol.h>
|
||||
|
||||
#include <game/client/animstate.h>
|
||||
#include <game/client/components/chat.h>
|
||||
#include <game/client/components/menu_background.h>
|
||||
#include <game/client/components/sounds.h>
|
||||
#include <game/client/gameclient.h>
|
||||
|
@ -1631,13 +1632,31 @@ void CMenus::RenderSettingsHUD(CUIRect MainView)
|
|||
g_Config.m_ClShowChat ^= 1;
|
||||
}
|
||||
|
||||
bool IsOldChat = !(g_Config.m_ClChatTee || g_Config.m_ClChatBackground);
|
||||
|
||||
Left.HSplitTop(20.0f, &Button, &Left);
|
||||
if(DoButton_CheckBox(&g_Config.m_ClChatTee, Localize("Use old chat style"), IsOldChat, &Button))
|
||||
{
|
||||
if(IsOldChat)
|
||||
{
|
||||
g_Config.m_ClChatTee = 1;
|
||||
g_Config.m_ClChatBackground = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_Config.m_ClChatTee = 0;
|
||||
g_Config.m_ClChatBackground = 0;
|
||||
}
|
||||
GameClient()->m_pChat->RebuildChat();
|
||||
}
|
||||
|
||||
Right.HSplitTop(20.0f, &Button, &Right);
|
||||
if(DoButton_CheckBox(&g_Config.m_ClChatTeamColors, Localize("Show names in chat in team colors"), g_Config.m_ClChatTeamColors, &Button))
|
||||
{
|
||||
g_Config.m_ClChatTeamColors ^= 1;
|
||||
}
|
||||
|
||||
Left.HSplitTop(20.0f, &Button, &Left);
|
||||
Right.HSplitTop(20.0f, &Button, &Right);
|
||||
if(DoButton_CheckBox(&g_Config.m_ClShowKillMessages, Localize("Show kill messages"), g_Config.m_ClShowKillMessages, &Button))
|
||||
{
|
||||
g_Config.m_ClShowKillMessages ^= 1;
|
||||
|
|
|
@ -2888,6 +2888,7 @@ void CGameClient::RefindSkins()
|
|||
}
|
||||
}
|
||||
m_pGhost->RefindSkin();
|
||||
m_pChat->RefindSkins();
|
||||
}
|
||||
|
||||
void CGameClient::LoadMapSettings()
|
||||
|
|
Loading…
Reference in a new issue