mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-11 10:38:20 +00:00
49bc150afd
On the one hand variables called "Dummy" would tell us whether the current action refers to the currently inactive tee ("dummy"). On the other hand, these variables could tell us whether the current action refers to the main connection to the server, or the secondary one. The latter use case is now renamed to "Client", with the choices `CLIENT_MAIN`, `CLIENT_DUMMY` (and `CLIENT_CONTACT`). Perhaps better names could be found, especially since `Client` also refers to the engine client class in the game code. I tried to not fix bugs unless it would complicate the code.
224 lines
5.8 KiB
C++
224 lines
5.8 KiB
C++
/* (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. */
|
|
#include <engine/graphics.h>
|
|
#include <engine/serverbrowser.h>
|
|
#include <engine/shared/config.h>
|
|
#include <game/generated/client_data.h>
|
|
#include <game/generated/protocol.h>
|
|
|
|
#include "chat.h"
|
|
#include "emoticon.h"
|
|
#include <game/client/animstate.h>
|
|
#include <game/client/render.h>
|
|
#include <game/client/ui.h>
|
|
#include <game/gamecore.h> // get_angle
|
|
|
|
#include <game/client/gameclient.h>
|
|
|
|
CEmoticon::CEmoticon()
|
|
{
|
|
OnReset();
|
|
}
|
|
|
|
void CEmoticon::ConKeyEmoticon(IConsole::IResult *pResult, void *pUserData)
|
|
{
|
|
CEmoticon *pSelf = (CEmoticon *)pUserData;
|
|
if(!pSelf->m_pClient->m_Snap.m_SpecInfo.m_Active && pSelf->Client()->State() != IClient::STATE_DEMOPLAYBACK)
|
|
pSelf->m_Active = pResult->GetInteger(0) != 0;
|
|
}
|
|
|
|
void CEmoticon::ConEmote(IConsole::IResult *pResult, void *pUserData)
|
|
{
|
|
((CEmoticon *)pUserData)->Emote(pResult->GetInteger(0));
|
|
}
|
|
|
|
void CEmoticon::OnConsoleInit()
|
|
{
|
|
Console()->Register("+emote", "", CFGFLAG_CLIENT, ConKeyEmoticon, this, "Open emote selector");
|
|
Console()->Register("emote", "i[emote-id]", CFGFLAG_CLIENT, ConEmote, this, "Use emote");
|
|
}
|
|
|
|
void CEmoticon::OnReset()
|
|
{
|
|
m_WasActive = false;
|
|
m_Active = false;
|
|
m_SelectedEmote = -1;
|
|
m_SelectedEyeEmote = -1;
|
|
}
|
|
|
|
void CEmoticon::OnRelease()
|
|
{
|
|
m_Active = false;
|
|
}
|
|
|
|
bool CEmoticon::OnMouseMove(float x, float y)
|
|
{
|
|
if(!m_Active)
|
|
return false;
|
|
|
|
UI()->ConvertMouseMove(&x, &y);
|
|
m_SelectorMouse += vec2(x, y);
|
|
return true;
|
|
}
|
|
|
|
void CEmoticon::DrawCircle(float x, float y, float r, int Segments)
|
|
{
|
|
RenderTools()->DrawCircle(x, y, r, Segments);
|
|
}
|
|
|
|
void CEmoticon::OnRender()
|
|
{
|
|
if(!m_Active)
|
|
{
|
|
if(m_WasActive && m_SelectedEmote != -1)
|
|
Emote(m_SelectedEmote);
|
|
if(m_WasActive && m_SelectedEyeEmote != -1)
|
|
EyeEmote(m_SelectedEyeEmote);
|
|
m_WasActive = false;
|
|
return;
|
|
}
|
|
|
|
if(m_pClient->m_Snap.m_SpecInfo.m_Active)
|
|
{
|
|
m_Active = false;
|
|
m_WasActive = false;
|
|
return;
|
|
}
|
|
|
|
m_WasActive = true;
|
|
|
|
if(length(m_SelectorMouse) > 170.0f)
|
|
m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f;
|
|
|
|
float SelectedAngle = angle(m_SelectorMouse) + 2 * pi / 24;
|
|
if(SelectedAngle < 0)
|
|
SelectedAngle += 2 * pi;
|
|
|
|
m_SelectedEmote = -1;
|
|
m_SelectedEyeEmote = -1;
|
|
if(length(m_SelectorMouse) > 110.0f)
|
|
m_SelectedEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTICONS);
|
|
else if(length(m_SelectorMouse) > 40.0f)
|
|
m_SelectedEyeEmote = (int)(SelectedAngle / (2 * pi) * NUM_EMOTES);
|
|
|
|
CUIRect Screen = *UI()->Screen();
|
|
|
|
UI()->MapScreen();
|
|
|
|
Graphics()->BlendNormal();
|
|
|
|
Graphics()->TextureClear();
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(0, 0, 0, 0.3f);
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 190.0f, 64);
|
|
Graphics()->QuadsEnd();
|
|
|
|
Graphics()->WrapClamp();
|
|
for(int i = 0; i < NUM_EMOTICONS; i++)
|
|
{
|
|
float Angle = 2 * pi * i / NUM_EMOTICONS;
|
|
if(Angle > pi)
|
|
Angle -= 2 * pi;
|
|
|
|
bool Selected = m_SelectedEmote == i;
|
|
|
|
float Size = Selected ? 80.0f : 50.0f;
|
|
|
|
Graphics()->TextureSet(GameClient()->m_EmoticonsSkin.m_SpriteEmoticons[i]);
|
|
Graphics()->QuadsSetSubset(0, 0, 1, 1);
|
|
|
|
Graphics()->QuadsBegin();
|
|
float NudgeX = 150.0f * cosf(Angle);
|
|
float NudgeY = 150.0f * sinf(Angle);
|
|
IGraphics::CQuadItem QuadItem(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY, Size, Size);
|
|
Graphics()->QuadsDraw(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
}
|
|
Graphics()->WrapNormal();
|
|
|
|
if(GameClient()->m_GameInfo.m_AllowEyeWheel && g_Config.m_ClEyeWheel)
|
|
{
|
|
Graphics()->TextureClear();
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(1.0, 1.0, 1.0, 0.3f);
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 100.0f, 64);
|
|
Graphics()->QuadsEnd();
|
|
|
|
CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[g_Config.m_ClDummy]].m_RenderInfo;
|
|
|
|
for(int i = 0; i < NUM_EMOTES; i++)
|
|
{
|
|
float Angle = 2 * pi * i / NUM_EMOTES;
|
|
if(Angle > pi)
|
|
Angle -= 2 * pi;
|
|
|
|
bool Selected = m_SelectedEyeEmote == i;
|
|
|
|
float NudgeX = 70.0f * cosf(Angle);
|
|
float NudgeY = 70.0f * sinf(Angle);
|
|
|
|
pTeeInfo->m_Size = Selected ? 64.0f : 48.0f;
|
|
RenderTools()->RenderTee(CAnimState::GetIdle(), pTeeInfo, i, vec2(-1, 0), vec2(Screen.w / 2 + NudgeX, Screen.h / 2 + NudgeY));
|
|
pTeeInfo->m_Size = 64.0f;
|
|
}
|
|
|
|
Graphics()->TextureClear();
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(0, 0, 0, 0.3f);
|
|
DrawCircle(Screen.w / 2, Screen.h / 2, 30.0f, 64);
|
|
Graphics()->QuadsEnd();
|
|
}
|
|
else
|
|
m_SelectedEyeEmote = -1;
|
|
|
|
Graphics()->WrapClamp();
|
|
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id);
|
|
Graphics()->QuadsBegin();
|
|
Graphics()->SetColor(1, 1, 1, 1);
|
|
IGraphics::CQuadItem QuadItem(m_SelectorMouse.x + Screen.w / 2, m_SelectorMouse.y + Screen.h / 2, 24, 24);
|
|
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
|
Graphics()->QuadsEnd();
|
|
Graphics()->WrapNormal();
|
|
}
|
|
|
|
void CEmoticon::Emote(int Emoticon)
|
|
{
|
|
CNetMsg_Cl_Emoticon Msg;
|
|
Msg.m_Emoticon = Emoticon;
|
|
Client()->SendPackMsgActive(&Msg, MSGFLAG_VITAL);
|
|
|
|
if(g_Config.m_ClDummyCopyMoves)
|
|
{
|
|
CMsgPacker Msg(NETMSGTYPE_CL_EMOTICON, false);
|
|
Msg.AddInt(Emoticon);
|
|
Client()->SendMsg(!g_Config.m_ClDummy, &Msg, MSGFLAG_VITAL);
|
|
}
|
|
}
|
|
|
|
void CEmoticon::EyeEmote(int Emote)
|
|
{
|
|
char aBuf[32];
|
|
switch(Emote)
|
|
{
|
|
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;
|
|
}
|
|
GameClient()->m_Chat.Say(0, aBuf);
|
|
}
|