diff --git a/src/game/client/components/spectator.cpp b/src/game/client/components/spectator.cpp index dd238d4d7..07c9c2107 100644 --- a/src/game/client/components/spectator.cpp +++ b/src/game/client/components/spectator.cpp @@ -1,5 +1,8 @@ /* (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 + #include #include #include @@ -133,6 +136,51 @@ void CSpectator::ConSpectatePrevious(IConsole::IResult *pResult, void *pUserData pSelf->Spectate(NewSpectatorID); } +void CSpectator::ConSpectateClosest(IConsole::IResult *pResult, void *pUserData) +{ + CSpectator *pSelf = (CSpectator *)pUserData; + int NewSpectatorID = -1; + + int IndexOfTeeBeingSpectated = -1; + for (int i = 0; i < MAX_CLIENTS; i++) + { + if(pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[i] && pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_ClientID == pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID) + { + IndexOfTeeBeingSpectated = i; + break; + } + } + + if(IndexOfTeeBeingSpectated == -1 || pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW) + { + //TODO: for now just behave like spectate_next when we're SPEC_FREEVIEW, but it would be better if we specate the tee closest to our mouse cursor + ConSpectateNext(pResult, pUserData); + return; + } + else + { + const CNetObj_Character &CurCharacter = pSelf->m_pClient->m_Snap.m_aCharacters[pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[IndexOfTeeBeingSpectated]->m_ClientID].m_Cur; + vec2 CurPosition(CurCharacter.m_X, CurCharacter.m_Y); + int ClosestDistance = INT_MAX; + for(int i = 0; i < MAX_CLIENTS; i++) + { + if(i == IndexOfTeeBeingSpectated || !pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[i] || pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_Team == TEAM_SPECTATORS) + continue; + + int ClientID = pSelf->m_pClient->m_Snap.m_paInfoByDDTeam[i]->m_ClientID; + const CNetObj_Character &MaybeClosestCharacter = pSelf->m_pClient->m_Snap.m_aCharacters[ClientID].m_Cur; + int Distance = distance(CurPosition, vec2(MaybeClosestCharacter.m_X, MaybeClosestCharacter.m_Y)); + if(NewSpectatorID == -1 || Distance < ClosestDistance) + { + NewSpectatorID = ClientID; + ClosestDistance = Distance; + } + } + } + if(NewSpectatorID > -1) + pSelf->Spectate(NewSpectatorID); +} + CSpectator::CSpectator() { OnReset(); @@ -145,6 +193,7 @@ void CSpectator::OnConsoleInit() Console()->Register("spectate", "i[spectator-id]", CFGFLAG_CLIENT, ConSpectate, this, "Switch spectator mode"); Console()->Register("spectate_next", "", CFGFLAG_CLIENT, ConSpectateNext, this, "Spectate the next player"); Console()->Register("spectate_previous", "", CFGFLAG_CLIENT, ConSpectatePrevious, this, "Spectate the previous player"); + Console()->Register("spectate_closest", "", CFGFLAG_CLIENT, ConSpectateClosest, this, "Spectate the closest player"); } bool CSpectator::OnMouseMove(float x, float y) diff --git a/src/game/client/components/spectator.h b/src/game/client/components/spectator.h index e04100817..faf4dbebe 100644 --- a/src/game/client/components/spectator.h +++ b/src/game/client/components/spectator.h @@ -26,6 +26,7 @@ class CSpectator : public CComponent static void ConSpectate(IConsole::IResult *pResult, void *pUserData); static void ConSpectateNext(IConsole::IResult *pResult, void *pUserData); static void ConSpectatePrevious(IConsole::IResult *pResult, void *pUserData); + static void ConSpectateClosest(IConsole::IResult *pResult, void *pUserData); public: CSpectator();