2010-11-20 10:37:14 +00:00
|
|
|
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
|
|
|
|
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/graphics.h>
|
|
|
|
#include <engine/shared/config.h>
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <game/generated/protocol.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2015-08-30 19:42:16 +00:00
|
|
|
#include "chat.h"
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "emoticon.h"
|
2020-09-26 19:41:58 +00:00
|
|
|
#include <game/client/animstate.h>
|
|
|
|
#include <game/client/render.h>
|
|
|
|
#include <game/client/ui.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2021-07-12 09:29:59 +00:00
|
|
|
#include <game/client/gameclient.h>
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CEmoticon::CEmoticon()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
OnReset();
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData)
|
2008-08-30 08:20:06 +00:00
|
|
|
{
|
2010-09-07 18:01:51 +00:00
|
|
|
CEmoticon *pSelf = (CEmoticon *)pUserData;
|
2011-03-12 17:07:57 +00:00
|
|
|
if(!pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active && pSelf->Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
|
|
|
pSelf->m_Active = pResult->GetInteger(0) != 0;
|
2008-08-30 08:20:06 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::ConEmote(IConsole::IResult *pResult, void *pUserData)
|
2008-08-31 13:14:28 +00:00
|
|
|
{
|
2015-11-14 23:31:24 +00:00
|
|
|
((CEmoticon *)pUserData)->Emote(pResult->GetInteger(0));
|
2008-08-31 13:14:28 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::OnConsoleInit()
|
2008-08-30 08:20:06 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Console()->Register("+emote", "", CFGFLAG_CLIENT, ConKeyEmoticon, this, "Open emote selector");
|
2015-12-28 15:14:52 +00:00
|
|
|
Console()->Register("emote", "i[emote-id]", CFGFLAG_CLIENT, ConEmote, this, "Use emote");
|
2008-08-30 08:20:06 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::OnReset()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_WasActive = false;
|
|
|
|
m_Active = false;
|
|
|
|
m_SelectedEmote = -1;
|
2015-11-14 23:31:24 +00:00
|
|
|
m_SelectedEyeEmote = -1;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-09-12 10:43:03 +00:00
|
|
|
void CEmoticon::OnRelease()
|
|
|
|
{
|
|
|
|
m_Active = false;
|
|
|
|
}
|
|
|
|
|
2022-06-06 20:03:24 +00:00
|
|
|
bool CEmoticon::OnCursorMove(float x, float y, IInput::ECursorType CursorType)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!m_Active)
|
2021-10-23 11:48:21 +00:00
|
|
|
return false;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2022-06-06 20:03:24 +00:00
|
|
|
UI()->ConvertMouseMove(&x, &y, CursorType);
|
2021-10-23 11:48:21 +00:00
|
|
|
m_SelectorMouse += vec2(x, y);
|
|
|
|
return true;
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::DrawCircle(float x, float y, float r, int Segments)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2014-10-11 18:05:48 +00:00
|
|
|
RenderTools()->DrawCircle(x, y, r, Segments);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CEmoticon::OnRender()
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(!m_Active)
|
2008-08-30 08:20:06 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_WasActive && m_SelectedEmote != -1)
|
|
|
|
Emote(m_SelectedEmote);
|
2015-11-14 23:31:24 +00:00
|
|
|
if(m_WasActive && m_SelectedEyeEmote != -1)
|
|
|
|
EyeEmote(m_SelectedEyeEmote);
|
2010-05-29 07:25:38 +00:00
|
|
|
m_WasActive = false;
|
2008-08-30 08:20:06 +00:00
|
|
|
return;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-07-11 10:02:45 +00:00
|
|
|
if(m_pClient->m_Snap.m_SpecInfo.m_Active)
|
|
|
|
{
|
|
|
|
m_Active = false;
|
|
|
|
m_WasActive = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_WasActive = true;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
if(length(m_SelectorMouse) > 170.0f)
|
2012-01-08 23:23:58 +00:00
|
|
|
m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2014-02-18 16:20:28 +00:00
|
|
|
float SelectedAngle = angle(m_SelectorMouse) + 2 * pi / 24;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(SelectedAngle < 0)
|
|
|
|
SelectedAngle += 2 * pi;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2015-08-30 19:42:16 +00:00
|
|
|
m_SelectedEmote = -1;
|
2015-11-14 23:31:24 +00:00
|
|
|
m_SelectedEyeEmote = -1;
|
2020-09-26 19:41:58 +00:00
|
|
|
if(length(m_SelectorMouse) > 110.0f)
|
|
|
|
m_SelectedEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTICONS);
|
2015-08-30 19:42:16 +00:00
|
|
|
else if(length(m_SelectorMouse) > 40.0f)
|
2020-09-26 19:41:58 +00:00
|
|
|
m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES);
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2011-04-13 18:37:12 +00:00
|
|
|
CUIRect Screen = *UI()->Screen();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2021-09-22 19:48:55 +00:00
|
|
|
UI()->MapScreen();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->BlendNormal();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->QuadsBegin();
|
2020-09-26 19:41:58 +00:00
|
|
|
Graphics()->SetColor(0, 0, 0, 0.3f);
|
|
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64);
|
2009-10-27 14:38:53 +00:00
|
|
|
Graphics()->QuadsEnd();
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2020-10-09 07:07:05 +00:00
|
|
|
Graphics()->WrapClamp();
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < NUM_EMOTICONS; i++)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
float Angle = 2 * pi * i / NUM_EMOTICONS;
|
|
|
|
if(Angle > pi)
|
|
|
|
Angle -= 2 * pi;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2015-11-14 23:31:24 +00:00
|
|
|
bool Selected = m_SelectedEmote == i;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2012-01-08 23:23:58 +00:00
|
|
|
float Size = Selected ? 80.0f : 50.0f;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2022-06-25 08:39:39 +00:00
|
|
|
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_aSpriteEmoticons[i]);
|
2020-10-09 07:07:05 +00:00
|
|
|
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
|
|
|
|
|
|
|
Graphics()->QuadsBegin();
|
2012-01-08 23:23:58 +00:00
|
|
|
float NudgeX = 150.0f * cosf(Angle);
|
|
|
|
float NudgeY = 150.0f * sinf(Angle);
|
2020-09-26 19:41:58 +00:00
|
|
|
IGraphics::CQuadItem QuadItem(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY, Size, Size);
|
2010-05-29 07:25:38 +00:00
|
|
|
Graphics()->QuadsDraw(&QuadItem, 1);
|
2020-10-09 07:07:05 +00:00
|
|
|
Graphics()->QuadsEnd();
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2020-10-09 07:07:05 +00:00
|
|
|
Graphics()->WrapNormal();
|
2015-11-14 23:31:24 +00:00
|
|
|
|
2019-06-03 19:52:14 +00:00
|
|
|
if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
|
2015-08-30 19:42:16 +00:00
|
|
|
{
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2015-08-30 19:42:16 +00:00
|
|
|
Graphics()->QuadsBegin();
|
2020-09-26 19:41:58 +00:00
|
|
|
Graphics()->SetColor(1.0, 1.0, 1.0, 0.3f);
|
|
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 100.0f, 64);
|
2015-08-30 19:42:16 +00:00
|
|
|
Graphics()->QuadsEnd();
|
2015-11-14 23:31:24 +00:00
|
|
|
|
2022-06-30 22:36:32 +00:00
|
|
|
CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_aLocalIDs[g_Config.m_ClDummy]].m_RenderInfo;
|
2015-11-14 23:31:24 +00:00
|
|
|
|
2020-09-26 19:41:58 +00:00
|
|
|
for(int i = 0; i < NUM_EMOTES; i++)
|
2015-08-30 19:42:16 +00:00
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
float Angle = 2 * pi * i / NUM_EMOTES;
|
|
|
|
if(Angle > pi)
|
|
|
|
Angle -= 2 * pi;
|
2015-11-14 23:31:24 +00:00
|
|
|
|
|
|
|
bool Selected = m_SelectedEyeEmote == i;
|
|
|
|
|
2015-08-30 19:42:16 +00:00
|
|
|
float NudgeX = 70.0f * cosf(Angle);
|
|
|
|
float NudgeY = 70.0f * sinf(Angle);
|
2016-09-26 18:56:13 +00:00
|
|
|
|
|
|
|
pTeeInfo->m_Size = Selected ? 64.0f : 48.0f;
|
2020-09-26 19:41:58 +00:00
|
|
|
RenderTools()->RenderTee(CAnimState::GetIdle(), pTeeInfo, i, vec2(-1, 0), vec2(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY));
|
2016-09-26 18:56:13 +00:00
|
|
|
pTeeInfo->m_Size = 64.0f;
|
2015-08-30 19:42:16 +00:00
|
|
|
}
|
2015-11-14 23:31:24 +00:00
|
|
|
|
2012-08-12 10:41:50 +00:00
|
|
|
Graphics()->TextureClear();
|
2015-08-30 19:42:16 +00:00
|
|
|
Graphics()->QuadsBegin();
|
2020-09-26 19:41:58 +00:00
|
|
|
Graphics()->SetColor(0, 0, 0, 0.3f);
|
|
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 30.0f, 64);
|
2015-08-30 19:42:16 +00:00
|
|
|
Graphics()->QuadsEnd();
|
|
|
|
}
|
2015-11-16 20:15:37 +00:00
|
|
|
else
|
|
|
|
m_SelectedEyeEmote = -1;
|
2008-08-27 15:48:50 +00:00
|
|
|
|
2022-05-27 17:30:20 +00:00
|
|
|
RenderTools()->RenderCursor(m_SelectorMouse + vec2(Screen.w, Screen.h) / 2, 24.0f);
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
|
|
|
|
2015-11-14 23:31:24 +00:00
|
|
|
void CEmoticon::Emote(int Emoticon)
|
2008-08-27 15:48:50 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Cl_Emoticon Msg;
|
|
|
|
Msg.m_Emoticon = Emoticon;
|
2022-01-21 00:54:14 +00:00
|
|
|
Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL);
|
2015-02-18 13:26:47 +00:00
|
|
|
|
|
|
|
if(g_Config.m_ClDummyCopyMoves)
|
|
|
|
{
|
2022-03-20 11:57:50 +00:00
|
|
|
CMsgPacker MsgDummy(NETMSGTYPE_CL_EMOTICON, false);
|
|
|
|
MsgDummy.AddInt(Emoticon);
|
|
|
|
Client()->SendMsg(!g_Config.m_ClDummy, &MsgDummy, MSGFLAG_VITAL);
|
2015-02-18 13:26:47 +00:00
|
|
|
}
|
2008-08-27 15:48:50 +00:00
|
|
|
}
|
2015-08-30 19:42:16 +00:00
|
|
|
|
2015-11-14 23:31:24 +00:00
|
|
|
void CEmoticon::EyeEmote(int Emote)
|
2015-08-30 19:42:16 +00:00
|
|
|
{
|
2015-11-16 20:15:37 +00:00
|
|
|
char aBuf[32];
|
|
|
|
switch(Emote)
|
2015-08-30 19:42:16 +00:00
|
|
|
{
|
2015-11-16 20:15:37 +00:00
|
|
|
case EMOTE_NORMAL:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote normal %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
|
|
|
case EMOTE_PAIN:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote pain %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
|
|
|
case EMOTE_HAPPY:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote happy %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
|
|
|
case EMOTE_SURPRISE:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote surprise %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
|
|
|
case EMOTE_ANGRY:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote angry %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
|
|
|
case EMOTE_BLINK:
|
|
|
|
str_format(aBuf, sizeof(aBuf), "/emote blink %d", g_Config.m_ClEyeDuration);
|
|
|
|
break;
|
2015-08-30 19:42:16 +00:00
|
|
|
}
|
2021-07-12 09:43:56 +00:00
|
|
|
GameClient()->m_Chat.Say(0, aBuf);
|
2015-08-30 19:42:16 +00:00
|
|
|
}
|