diff options
Diffstat (limited to 'src/game/client/components/spectator.cpp')
| -rw-r--r-- | src/game/client/components/spectator.cpp | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp new file mode 100644 index 00000000..18035248 --- /dev/null +++ b/src/game/client/components/spectator.cpp @@ -0,0 +1,172 @@ +/* (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/textrender.h> +#include <engine/shared/config.h> + +#include <game/generated/client_data.h> +#include <game/generated/protocol.h> + +#include <game/client/animstate.h> +#include <game/client/render.h> + +#include "spectator.h" + + +void CSpectator::ConKeySpectator(IConsole::IResult *pResult, void *pUserData) +{ + CSpectator *pSelf = (CSpectator *)pUserData; + if(pSelf->m_pClient->m_Snap.m_Spectate) + pSelf->m_Active = pResult->GetInteger(0) != 0; +} + +void CSpectator::ConSpectate(IConsole::IResult *pResult, void *pUserData) +{ + ((CSpectator *)pUserData)->Spectate(pResult->GetInteger(0)); +} + +CSpectator::CSpectator() +{ + OnReset(); +} + +void CSpectator::OnConsoleInit() +{ + Console()->Register("+spectate", "", CFGFLAG_CLIENT, ConKeySpectator, this, "Open spectator mode selector"); + Console()->Register("spectate", "i", CFGFLAG_CLIENT, ConSpectate, this, "Switch spectator mode"); +} + +bool CSpectator::OnMouseMove(float x, float y) +{ + if(!m_Active) + return false; + + m_SelectorMouse += vec2(x,y); + return true; +} + +void CSpectator::OnRelease() +{ + OnReset(); +} + +void CSpectator::OnRender() +{ + if(!m_Active) + { + if(m_WasActive) + { + if(m_SelectedSpectatorID != NO_SELECTION) + Spectate(m_SelectedSpectatorID); + OnReset(); + } + return; + } + + m_WasActive = true; + m_SelectedSpectatorID = NO_SELECTION; + + // draw background + float Width = 400*3.0f*Graphics()->ScreenAspect(); + float Height = 400*3.0f; + + Graphics()->MapScreen(0, 0, Width, Height); + + Graphics()->BlendNormal(); + Graphics()->TextureSet(-1); + Graphics()->QuadsBegin(); + Graphics()->SetColor(0.0f, 0.0f, 0.0f, 0.3f); + RenderTools()->DrawRoundRect(Width/2.0f-300.0f, Height/2.0f-300.0f, 600.0f, 600.0f, 20.0f); + Graphics()->QuadsEnd(); + + // clamp mouse position to selector area + m_SelectorMouse.x = clamp(m_SelectorMouse.x, -280.0f, 280.0f); + m_SelectorMouse.y = clamp(m_SelectorMouse.y, -280.0f, 280.0f); + + // draw selections + float FontSize = 20.0f; + float StartY = -190.0f; + float LineHeight = 60.0f; + bool Selected = false; + + int SpectatorID = m_pClient->m_Snap.m_pSpectatorInfo ? m_pClient->m_Snap.m_pSpectatorInfo->m_SpectatorID : SPEC_FREEVIEW; + if(SpectatorID == SPEC_FREEVIEW) + { + Graphics()->TextureSet(-1); + Graphics()->QuadsBegin(); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); + RenderTools()->DrawRoundRect(Width/2.0f-280.0f, Height/2.0f-280.0f, 270.0f, 60.0f, 20.0f); + Graphics()->QuadsEnd(); + } + + if(m_SelectorMouse.x >= -280.0f && m_SelectorMouse.x <= -10.0f && + m_SelectorMouse.y >= -280.0f && m_SelectorMouse.y <= -220.0f) + { + m_SelectedSpectatorID = SPEC_FREEVIEW; + Selected = true; + } + TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f); + TextRender()->Text(0, Width/2.0f-240.0f, Height/2.0f-265.0f, FontSize, Localize("Free-View"), -1); + + float x = -270.0f, y = StartY; + for(int i = 0, Count = 0; i < MAX_CLIENTS; ++i) + { + if(!m_pClient->m_Snap.m_paPlayerInfos[i] || m_pClient->m_Snap.m_paPlayerInfos[i]->m_Team == TEAM_SPECTATORS) + continue; + + if(++Count%9 == 0) + { + x += 290.0f; + y = StartY; + } + + if(SpectatorID == i) + { + Graphics()->TextureSet(-1); + Graphics()->QuadsBegin(); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 0.25f); + RenderTools()->DrawRoundRect(Width/2.0f+x-10.0f, Height/2.0f+y-10.0f, 270.0f, 60.0f, 20.0f); + Graphics()->QuadsEnd(); + } + + Selected = false; + if(m_SelectorMouse.x >= x-10.0f && m_SelectorMouse.x <= x+260.0f && + m_SelectorMouse.y >= y-10.0f && m_SelectorMouse.y <= y+50.0f) + { + m_SelectedSpectatorID = i; + Selected = true; + } + TextRender()->TextColor(1.0f, 1.0f, 1.0f, Selected?1.0f:0.5f); + TextRender()->Text(0, Width/2.0f+x+50.0f, Height/2.0f+y+5.0f, FontSize, m_pClient->m_aClients[i].m_aName, 220.0f); + + CTeeRenderInfo TeeInfo = m_pClient->m_aClients[i].m_RenderInfo; + RenderTools()->RenderTee(CAnimState::GetIdle(), &TeeInfo, EMOTE_NORMAL, vec2(1.0f, 0.0f), vec2(Width/2.0f+x+20.0f, Height/2.0f+y+20.0f)); + + y += LineHeight; + } + + // draw cursor + Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); + Graphics()->QuadsBegin(); + Graphics()->SetColor(1.0f, 1.0f, 1.0f, 1.0f); + IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Width/2.0f, m_SelectorMouse.y+Height/2.0f, 48.0f, 48.0f); + Graphics()->QuadsDrawTL(&QuadItem, 1); + Graphics()->QuadsEnd(); +} + +void CSpectator::OnReset() +{ + m_WasActive = false; + m_Active = false; + m_SelectedSpectatorID = NO_SELECTION; +} + +void CSpectator::Spectate(int SpectatorID) +{ + if(m_pClient->m_Snap.m_pSpectatorInfo && m_pClient->m_Snap.m_pSpectatorInfo->m_SpectatorID == SpectatorID) + return; + + CNetMsg_Cl_SetSpectatorMode Msg; + Msg.m_SpectatorID = SpectatorID; + Client()->SendPackMsg(&Msg, MSGFLAG_VITAL); +} |