mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
Improved spectator mode closes #1367
- follow flag - click a player/a flag to follow in world-free mode - click to go into the world-free mode while follow-mode
This commit is contained in:
parent
16965e4bd6
commit
85b2f98d71
|
@ -37,7 +37,11 @@ enum
|
|||
FLAG_ATSTAND,
|
||||
FLAG_TAKEN,
|
||||
|
||||
SPEC_FREEVIEW=-1,
|
||||
SPEC_PLAYER=0,
|
||||
SPEC_FREEVIEW,
|
||||
SPEC_FLAGRED,
|
||||
SPEC_FLAGBLUE,
|
||||
NUM_SPECMODES,
|
||||
};
|
||||
'''
|
||||
|
||||
|
@ -166,7 +170,8 @@ Objects = [
|
|||
]),
|
||||
|
||||
NetObject("SpectatorInfo", [
|
||||
NetIntRange("m_SpectatorID", 'SPEC_FREEVIEW', 'MAX_CLIENTS-1'),
|
||||
NetIntRange("m_SpecMode", 0, 'NUM_SPECMODES-1'),
|
||||
NetIntRange("m_SpectatorID", -1, 'MAX_CLIENTS-1'),
|
||||
NetIntAny("m_X"),
|
||||
NetIntAny("m_Y"),
|
||||
]),
|
||||
|
@ -356,7 +361,8 @@ Messages = [
|
|||
]),
|
||||
|
||||
NetMessage("Cl_SetSpectatorMode", [
|
||||
NetIntRange("m_SpectatorID", 'SPEC_FREEVIEW', 'MAX_CLIENTS-1'),
|
||||
NetIntRange("m_SpecMode", 0, 'NUM_SPECMODES'),
|
||||
NetIntRange("m_SpectatorID", -1, 'MAX_CLIENTS-1'),
|
||||
]),
|
||||
|
||||
NetMessage("Cl_StartInfo", [
|
||||
|
|
|
@ -541,8 +541,25 @@ void CHud::RenderSpectatorHud()
|
|||
char aName[64];
|
||||
str_format(aName, sizeof(aName), "%2d: %s", m_pClient->m_Snap.m_SpecInfo.m_SpectatorID, g_Config.m_ClShowsocial ? m_pClient->m_aClients[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID].m_aName : "");
|
||||
char aBuf[128];
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Spectate"), m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW ?
|
||||
aName : Localize("Free-View"));
|
||||
switch(m_pClient->m_Snap.m_SpecInfo.m_SpecMode)
|
||||
{
|
||||
case SPEC_FREEVIEW:
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Spectate"), Localize("Free-View"));
|
||||
break;
|
||||
case SPEC_PLAYER:
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Spectate"), aName);
|
||||
break;
|
||||
case SPEC_FLAGRED:
|
||||
case SPEC_FLAGBLUE:
|
||||
char aFlag[64];
|
||||
str_format(aFlag, sizeof(aFlag), "%s flag", Localize(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FLAGRED ? "red" : "blue"));
|
||||
|
||||
if (m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != -1)
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s (%s)", Localize("Spectate"), aFlag, aName);
|
||||
else
|
||||
str_format(aBuf, sizeof(aBuf), "%s: %s", Localize("Spectate"), aFlag);
|
||||
break;
|
||||
}
|
||||
TextRender()->Text(0, m_Width-174.0f, m_Height-13.0f, 8.0f, aBuf, -1);
|
||||
}
|
||||
|
||||
|
@ -565,7 +582,7 @@ void CHud::OnRender()
|
|||
RenderHealthAndAmmo(m_pClient->m_Snap.m_pLocalCharacter);
|
||||
else if(m_pClient->m_Snap.m_SpecInfo.m_Active)
|
||||
{
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW)
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID != -1)
|
||||
RenderHealthAndAmmo(&m_pClient->m_Snap.m_aCharacters[m_pClient->m_Snap.m_SpecInfo.m_SpectatorID].m_Cur);
|
||||
RenderSpectatorHud();
|
||||
}
|
||||
|
|
|
@ -24,37 +24,61 @@ void CSpectator::ConKeySpectator(IConsole::IResult *pResult, void *pUserData)
|
|||
|
||||
void CSpectator::ConSpectate(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
((CSpectator *)pUserData)->Spectate(pResult->GetInteger(0));
|
||||
int SpectatorID = pResult->GetInteger(0);
|
||||
if (SpectatorID >= 0)
|
||||
((CSpectator *)pUserData)->Spectate(SPEC_PLAYER, SpectatorID);
|
||||
else
|
||||
((CSpectator *)pUserData)->Spectate(-SpectatorID, -1);
|
||||
}
|
||||
|
||||
void CSpectator::ConSpectateNext(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CSpectator *pSelf = (CSpectator *)pUserData;
|
||||
int NewSpecMode = SPEC_PLAYER;
|
||||
int NewSpectatorID;
|
||||
bool GotNewSpectatorID = false;
|
||||
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FREEVIEW)
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
NewSpecMode = SPEC_FLAGRED;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID + 1; i < MAX_CLIENTS; i++)
|
||||
if(pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS && pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FLAGRED)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
NewSpecMode = SPEC_FLAGBLUE;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID)
|
||||
{
|
||||
for(int i = pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID + 1; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID)
|
||||
|
@ -69,18 +93,26 @@ void CSpectator::ConSpectateNext(IConsole::IResult *pResult, void *pUserData)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID && pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
|
||||
{
|
||||
NewSpecMode = SPEC_FLAGRED;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
}
|
||||
}
|
||||
if(GotNewSpectatorID)
|
||||
pSelf->Spectate(NewSpectatorID);
|
||||
pSelf->Spectate(NewSpecMode, NewSpectatorID);
|
||||
}
|
||||
|
||||
void CSpectator::ConSpectatePrevious(IConsole::IResult *pResult, void *pUserData)
|
||||
{
|
||||
CSpectator *pSelf = (CSpectator *)pUserData;
|
||||
int NewSpecMode = SPEC_PLAYER;
|
||||
int NewSpectatorID;
|
||||
bool GotNewSpectatorID = false;
|
||||
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
|
||||
if(pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FREEVIEW)
|
||||
{
|
||||
for(int i = MAX_CLIENTS -1; i > -1; i--)
|
||||
{
|
||||
|
@ -91,17 +123,33 @@ void CSpectator::ConSpectatePrevious(IConsole::IResult *pResult, void *pUserData
|
|||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
if(!GotNewSpectatorID && pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
|
||||
{
|
||||
NewSpecMode = SPEC_FLAGBLUE;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int i = pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID - 1; i > -1; i--)
|
||||
if(pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS && pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FLAGBLUE)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
NewSpecMode = SPEC_FLAGRED;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID)
|
||||
{
|
||||
for(int i = pSelf->m_pClient->m_Snap.m_SpecInfo.m_SpectatorID - 1; i > -1; i--)
|
||||
{
|
||||
if(!pSelf->m_pClient->m_aClients[i].m_Active || pSelf->m_pClient->m_aClients[i].m_Team == TEAM_SPECTATORS)
|
||||
continue;
|
||||
|
||||
NewSpectatorID = i;
|
||||
GotNewSpectatorID = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID)
|
||||
|
@ -116,9 +164,16 @@ void CSpectator::ConSpectatePrevious(IConsole::IResult *pResult, void *pUserData
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!GotNewSpectatorID && pSelf->m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
|
||||
{
|
||||
NewSpecMode = SPEC_FLAGBLUE;
|
||||
NewSpectatorID = -1;
|
||||
GotNewSpectatorID = true;
|
||||
}
|
||||
}
|
||||
if(GotNewSpectatorID)
|
||||
pSelf->Spectate(NewSpectatorID);
|
||||
pSelf->Spectate(NewSpecMode, NewSpectatorID);
|
||||
}
|
||||
|
||||
CSpectator::CSpectator()
|
||||
|
@ -155,8 +210,8 @@ void CSpectator::OnRender()
|
|||
{
|
||||
if(m_WasActive)
|
||||
{
|
||||
if(m_SelectedSpectatorID != NO_SELECTION)
|
||||
Spectate(m_SelectedSpectatorID);
|
||||
if(m_SelectedSpecMode != NO_SELECTION)
|
||||
Spectate(m_SelectedSpecMode, m_SelectedSpectatorID);
|
||||
m_WasActive = false;
|
||||
}
|
||||
return;
|
||||
|
@ -170,7 +225,8 @@ void CSpectator::OnRender()
|
|||
}
|
||||
|
||||
m_WasActive = true;
|
||||
m_SelectedSpectatorID = NO_SELECTION;
|
||||
m_SelectedSpecMode = NO_SELECTION;
|
||||
m_SelectedSpectatorID = -1;
|
||||
|
||||
// draw background
|
||||
float Width = 400*3.0f*Graphics()->ScreenAspect();
|
||||
|
@ -194,7 +250,7 @@ void CSpectator::OnRender()
|
|||
|
||||
if(m_pClient->m_aClients[m_pClient->m_LocalClientID].m_Team == TEAM_SPECTATORS)
|
||||
{
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SPEC_FREEVIEW)
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_FREEVIEW)
|
||||
{
|
||||
Rect.x = Width/2.0f-280.0f;
|
||||
Rect.y = Height/2.0f-280.0f;
|
||||
|
@ -206,14 +262,55 @@ void CSpectator::OnRender()
|
|||
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;
|
||||
m_SelectedSpecMode = 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;
|
||||
//
|
||||
float x = 20.0f, y = -270;
|
||||
if (m_pClient->m_GameInfo.m_GameFlags&GAMEFLAG_FLAGS)
|
||||
{
|
||||
for(int Flag = SPEC_FLAGRED; Flag <= SPEC_FLAGBLUE; ++Flag)
|
||||
{
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == Flag)
|
||||
{
|
||||
Rect.x = Width/2.0f+x-10.0f;
|
||||
Rect.y = Height/2.0f+y-10.0f;
|
||||
Rect.w = 120.0f;
|
||||
Rect.h = 60.0f;
|
||||
RenderTools()->DrawRoundRect(&Rect, vec4(1.0f, 1.0f, 1.0f, 0.25f), 20.0f);
|
||||
}
|
||||
|
||||
Selected = false;
|
||||
if(m_SelectorMouse.x >= x-10.0f && m_SelectorMouse.x <= x+110.0f &&
|
||||
m_SelectorMouse.y >= y-10.0f && m_SelectorMouse.y <= y+50.0f)
|
||||
{
|
||||
m_SelectedSpecMode = Flag;
|
||||
Selected = true;
|
||||
}
|
||||
|
||||
Graphics()->BlendNormal();
|
||||
Graphics()->TextureSet(g_pData->m_aImages[IMAGE_GAME].m_Id);
|
||||
Graphics()->QuadsBegin();
|
||||
|
||||
RenderTools()->SelectSprite(Flag == SPEC_FLAGRED ? SPRITE_FLAG_RED : SPRITE_FLAG_BLUE);
|
||||
|
||||
float Size = LineHeight/1.5f + (Selected ? 12.0f : 8.0f);
|
||||
float FlagWidth = Width/2.0f + x + 40.0f + (Selected ? -3.0f : -2.0f);
|
||||
float FlagHeight = Height/2.0f + y + (Selected ? -6.0f : -4.0f);
|
||||
|
||||
IGraphics::CQuadItem QuadItem(FlagWidth, FlagHeight, Size/2.0f, Size);
|
||||
Graphics()->QuadsDrawTL(&QuadItem, 1);
|
||||
Graphics()->QuadsEnd();
|
||||
|
||||
x+=140.0f;
|
||||
}
|
||||
}
|
||||
|
||||
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_aClients[i].m_Team == TEAM_SPECTATORS ||
|
||||
|
@ -227,7 +324,7 @@ void CSpectator::OnRender()
|
|||
y = StartY;
|
||||
}
|
||||
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == i)
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SPEC_PLAYER && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == i)
|
||||
{
|
||||
Rect.x = Width/2.0f+x-10.0f;
|
||||
Rect.y = Height/2.0f+y-10.0f;
|
||||
|
@ -240,6 +337,7 @@ void CSpectator::OnRender()
|
|||
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_SelectedSpecMode = SPEC_PLAYER;
|
||||
m_SelectedSpectatorID = i;
|
||||
Selected = true;
|
||||
}
|
||||
|
@ -285,21 +383,24 @@ void CSpectator::OnReset()
|
|||
{
|
||||
m_WasActive = false;
|
||||
m_Active = false;
|
||||
m_SelectedSpectatorID = NO_SELECTION;
|
||||
m_SelectedSpecMode = NO_SELECTION;
|
||||
m_SelectedSpectatorID = -1;
|
||||
}
|
||||
|
||||
void CSpectator::Spectate(int SpectatorID)
|
||||
void CSpectator::Spectate(int SpecMode, int SpectatorID)
|
||||
{
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK)
|
||||
{
|
||||
m_pClient->m_DemoSpecID = clamp(SpectatorID, (int)SPEC_FREEVIEW, MAX_CLIENTS-1);
|
||||
m_pClient->m_DemoSpecMode = clamp(SpecMode, 0, NUM_SPECMODES-1);
|
||||
m_pClient->m_DemoSpecID = clamp(SpectatorID, -1, MAX_CLIENTS-1);
|
||||
return;
|
||||
}
|
||||
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SpectatorID)
|
||||
if(m_pClient->m_Snap.m_SpecInfo.m_SpecMode == SpecMode && m_pClient->m_Snap.m_SpecInfo.m_SpectatorID == SpectatorID)
|
||||
return;
|
||||
|
||||
CNetMsg_Cl_SetSpectatorMode Msg;
|
||||
Msg.m_SpecMode = SpecMode;
|
||||
Msg.m_SpectatorID = SpectatorID;
|
||||
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
|
||||
}
|
||||
|
|
|
@ -10,13 +10,14 @@ class CSpectator : public CComponent
|
|||
{
|
||||
enum
|
||||
{
|
||||
NO_SELECTION=-2,
|
||||
NO_SELECTION=-1,
|
||||
};
|
||||
|
||||
bool m_Active;
|
||||
bool m_WasActive;
|
||||
|
||||
int m_SelectedSpectatorID;
|
||||
int m_SelectedSpecMode;
|
||||
vec2 m_SelectorMouse;
|
||||
|
||||
static void ConKeySpectator(IConsole::IResult *pResult, void *pUserData);
|
||||
|
@ -33,7 +34,7 @@ public:
|
|||
virtual void OnRelease();
|
||||
virtual void OnReset();
|
||||
|
||||
void Spectate(int SpectatorID);
|
||||
void Spectate(int SpecMode, int SpectatorID);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -364,7 +364,8 @@ void CGameClient::OnReset()
|
|||
m_LocalClientID = -1;
|
||||
m_TeamCooldownTick = 0;
|
||||
mem_zero(&m_GameInfo, sizeof(m_GameInfo));
|
||||
m_DemoSpecID = SPEC_FREEVIEW;
|
||||
m_DemoSpecMode = SPEC_FREEVIEW;
|
||||
m_DemoSpecID = -1;
|
||||
m_Tuning = CTuningParams();
|
||||
}
|
||||
|
||||
|
@ -393,7 +394,7 @@ void CGameClient::UpdatePositions()
|
|||
if(m_Snap.m_SpecInfo.m_Active)
|
||||
{
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER &&
|
||||
m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW)
|
||||
m_Snap.m_SpecInfo.m_SpectatorID != -1)
|
||||
{
|
||||
m_Snap.m_SpecInfo.m_Position = mix(
|
||||
vec2(m_Snap.m_aCharacters[m_Snap.m_SpecInfo.m_SpectatorID].m_Prev.m_X, m_Snap.m_aCharacters[m_Snap.m_SpecInfo.m_SpectatorID].m_Prev.m_Y),
|
||||
|
@ -401,7 +402,7 @@ void CGameClient::UpdatePositions()
|
|||
Client()->IntraGameTick());
|
||||
m_Snap.m_SpecInfo.m_UsePosition = true;
|
||||
}
|
||||
else if(m_Snap.m_pSpectatorInfo && (Client()->State() == IClient::STATE_DEMOPLAYBACK || m_Snap.m_SpecInfo.m_SpectatorID != SPEC_FREEVIEW))
|
||||
else if(m_Snap.m_pSpectatorInfo && (Client()->State() == IClient::STATE_DEMOPLAYBACK || m_Snap.m_SpecInfo.m_SpecMode != SPEC_FREEVIEW))
|
||||
{
|
||||
if(m_Snap.m_pPrevSpectatorInfo)
|
||||
m_Snap.m_SpecInfo.m_Position = mix(vec2(m_Snap.m_pPrevSpectatorInfo->m_X, m_Snap.m_pPrevSpectatorInfo->m_Y),
|
||||
|
@ -535,8 +536,10 @@ void CGameClient::OnMessage(int MsgId, CUnpacker *pUnpacker)
|
|||
case GAMEMSG_CTF_GRAB:
|
||||
if(m_SuppressEvents)
|
||||
return;
|
||||
if(m_LocalClientID != -1 && (m_aClients[m_LocalClientID].m_Team != aParaI[0] ||
|
||||
(m_Snap.m_SpecInfo.m_Active && m_Snap.m_SpecInfo.m_SpectatorID != -1 && m_aClients[m_Snap.m_SpecInfo.m_SpectatorID].m_Team != aParaI[0])))
|
||||
if(m_LocalClientID != -1 && (m_aClients[m_LocalClientID].m_Team != aParaI[0] || (m_Snap.m_SpecInfo.m_Active &&
|
||||
(m_Snap.m_SpecInfo.m_SpectatorID != -1 && m_aClients[m_Snap.m_SpecInfo.m_SpectatorID].m_Team != aParaI[0]) ||
|
||||
(m_Snap.m_SpecInfo.m_SpecMode == SPEC_FLAGRED && aParaI[0] != TEAM_RED) ||
|
||||
(m_Snap.m_SpecInfo.m_SpecMode == SPEC_FLAGBLUE && aParaI[0] != TEAM_BLUE))))
|
||||
m_pSounds->Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_GRAB_PL);
|
||||
else
|
||||
m_pSounds->Enqueue(CSounds::CHN_GLOBAL, SOUND_CTF_GRAB_EN);
|
||||
|
@ -979,7 +982,8 @@ void CGameClient::OnNewSnapshot()
|
|||
if(m_aClients[ClientID].m_Team == TEAM_SPECTATORS)
|
||||
{
|
||||
m_Snap.m_SpecInfo.m_Active = true;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW;
|
||||
m_Snap.m_SpecInfo.m_SpecMode = SPEC_FREEVIEW;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1012,6 +1016,7 @@ void CGameClient::OnNewSnapshot()
|
|||
m_Snap.m_pSpectatorInfo = (const CNetObj_SpectatorInfo *)pData;
|
||||
m_Snap.m_pPrevSpectatorInfo = (const CNetObj_SpectatorInfo *)Client()->SnapFindItem(IClient::SNAP_PREV, NETOBJTYPE_SPECTATORINFO, Item.m_ID);
|
||||
m_Snap.m_SpecInfo.m_Active = true;
|
||||
m_Snap.m_SpecInfo.m_SpecMode = m_Snap.m_pSpectatorInfo->m_SpecMode;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = m_Snap.m_pSpectatorInfo->m_SpectatorID;
|
||||
}
|
||||
else if(Item.m_Type == NETOBJTYPE_GAMEDATA)
|
||||
|
@ -1059,10 +1064,24 @@ void CGameClient::OnNewSnapshot()
|
|||
{
|
||||
m_Snap.m_SpecInfo.m_Active = true;
|
||||
if(Client()->State() == IClient::STATE_DEMOPLAYBACK && DemoPlayer()->GetDemoType() == IDemoPlayer::DEMOTYPE_SERVER &&
|
||||
m_DemoSpecID != SPEC_FREEVIEW && m_Snap.m_aCharacters[m_DemoSpecID].m_Active)
|
||||
m_DemoSpecID != -1 && m_Snap.m_aCharacters[m_DemoSpecID].m_Active)
|
||||
{
|
||||
m_Snap.m_SpecInfo.m_SpecMode = SPEC_PLAYER;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID;
|
||||
}
|
||||
else
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = SPEC_FREEVIEW;
|
||||
{
|
||||
if (m_DemoSpecMode == SPEC_PLAYER)
|
||||
{
|
||||
m_Snap.m_SpecInfo.m_SpecMode = SPEC_FREEVIEW;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Snap.m_SpecInfo.m_SpecMode = m_DemoSpecMode;
|
||||
m_Snap.m_SpecInfo.m_SpectatorID = m_DemoSpecID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort player infos by score
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
};
|
||||
int m_ServerMode;
|
||||
|
||||
int m_DemoSpecMode;
|
||||
int m_DemoSpecID;
|
||||
|
||||
vec2 m_LocalCharacterPos;
|
||||
|
@ -138,6 +139,7 @@ public:
|
|||
struct CSpectateInfo
|
||||
{
|
||||
bool m_Active;
|
||||
int m_SpecMode;
|
||||
int m_SpectatorID;
|
||||
bool m_UsePosition;
|
||||
vec2 m_Position;
|
||||
|
|
|
@ -42,7 +42,7 @@ void CPickup::Tick()
|
|||
return;
|
||||
}
|
||||
// Check if a player intersected us
|
||||
CCharacter *pChr = GameServer()->m_World.ClosestCharacter(m_Pos, 20.0f, 0);
|
||||
CCharacter *pChr = (CCharacter *)GameServer()->m_World.ClosestEntity(m_Pos, 20.0f, CGameWorld::ENTTYPE_CHARACTER, 0);
|
||||
if(pChr && pChr->IsAlive())
|
||||
{
|
||||
// player picked us up, is someone was hooking us, let them go
|
||||
|
|
|
@ -628,7 +628,7 @@ void CGameContext::OnClientEnter(int ClientID)
|
|||
|
||||
// local info
|
||||
NewClientInfoMsg.m_Local = 1;
|
||||
Server()->SendPackMsg(&NewClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID);
|
||||
Server()->SendPackMsg(&NewClientInfoMsg, MSGFLAG_VITAL|MSGFLAG_NORECORD, ClientID);
|
||||
|
||||
if(Server()->DemoRecorder_IsRecording())
|
||||
{
|
||||
|
@ -923,7 +923,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
|
|||
return;
|
||||
|
||||
pPlayer->m_LastSetSpectatorMode = Server()->Tick();
|
||||
if(!pPlayer->SetSpectatorID(pMsg->m_SpectatorID))
|
||||
if(!pPlayer->SetSpectatorID(pMsg->m_SpecMode, pMsg->m_SpectatorID))
|
||||
SendGameMsg(GAMEMSG_SPEC_INVALIDID, ClientID);
|
||||
}
|
||||
else if (MsgID == NETMSGTYPE_CL_EMOTICON && !m_World.m_Paused)
|
||||
|
|
|
@ -232,14 +232,14 @@ CCharacter *CGameWorld::IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, v
|
|||
}
|
||||
|
||||
|
||||
CCharacter *CGameWorld::ClosestCharacter(vec2 Pos, float Radius, CEntity *pNotThis)
|
||||
CEntity *CGameWorld::ClosestEntity(vec2 Pos, float Radius, int Type, CEntity *pNotThis)
|
||||
{
|
||||
// Find other players
|
||||
float ClosestRange = Radius*2;
|
||||
CCharacter *pClosest = 0;
|
||||
CEntity *pClosest = 0;
|
||||
|
||||
CCharacter *p = (CCharacter *)GameServer()->m_World.FindFirst(ENTTYPE_CHARACTER);
|
||||
for(; p; p = (CCharacter *)p->TypeNext())
|
||||
CEntity *p = GameServer()->m_World.FindFirst(Type);
|
||||
for(; p; p = p->TypeNext())
|
||||
{
|
||||
if(p == pNotThis)
|
||||
continue;
|
||||
|
|
|
@ -68,6 +68,21 @@ public:
|
|||
*/
|
||||
int FindEntities(vec2 Pos, float Radius, CEntity **ppEnts, int Max, int Type);
|
||||
|
||||
/*
|
||||
Function: closest_CEntity
|
||||
Finds the closest CEntity of a type to a specific point.
|
||||
|
||||
Arguments:
|
||||
pos - The center position.
|
||||
radius - How far off the CEntity is allowed to be
|
||||
type - Type of the entities to find.
|
||||
notthis - Entity to ignore
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest CCharacter or NULL if no CCharacter is close enough.
|
||||
*/
|
||||
CEntity *ClosestEntity(vec2 Pos, float Radius, int Type, CEntity *pNotThis);
|
||||
|
||||
/*
|
||||
Function: interserct_CCharacter
|
||||
Finds the closest CCharacter that intersects the line.
|
||||
|
@ -84,20 +99,6 @@ public:
|
|||
*/
|
||||
class CCharacter *IntersectCharacter(vec2 Pos0, vec2 Pos1, float Radius, vec2 &NewPos, class CEntity *pNotThis = 0);
|
||||
|
||||
/*
|
||||
Function: closest_CCharacter
|
||||
Finds the closest CCharacter to a specific point.
|
||||
|
||||
Arguments:
|
||||
pos - The center position.
|
||||
radius - How far off the CCharacter is allowed to be
|
||||
notthis - Entity to ignore
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest CCharacter or NULL if no CCharacter is close enough.
|
||||
*/
|
||||
class CCharacter *ClosestCharacter(vec2 Pos, float Radius, CEntity *ppNotThis);
|
||||
|
||||
/*
|
||||
Function: insert_entity
|
||||
Adds an entity to the world.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* If you are missing that file, acquire a complete release at teeworlds.com. */
|
||||
|
||||
#include "entities/character.h"
|
||||
#include "entities/flag.h"
|
||||
#include "gamecontext.h"
|
||||
#include "gamecontroller.h"
|
||||
#include "player.h"
|
||||
|
@ -20,7 +21,10 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy)
|
|||
m_pCharacter = 0;
|
||||
m_ClientID = ClientID;
|
||||
m_Team = GameServer()->m_pController->GetStartTeam();
|
||||
m_SpectatorID = SPEC_FREEVIEW;
|
||||
m_SpecMode = SPEC_FREEVIEW;
|
||||
m_SpectatorID = -1;
|
||||
m_pSpecFlag = 0;
|
||||
m_ActiveSpecSwitch = 0;
|
||||
m_LastActionTick = Server()->Tick();
|
||||
m_TeamChangeTick = Server()->Tick();
|
||||
m_InactivityTickCounter = 0;
|
||||
|
@ -73,12 +77,20 @@ void CPlayer::Tick()
|
|||
|
||||
if(!GameServer()->m_pController->IsGamePaused())
|
||||
{
|
||||
if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW)
|
||||
if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpecMode == SPEC_FREEVIEW)
|
||||
m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -500.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f));
|
||||
|
||||
if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick() && !m_DeadSpecMode)
|
||||
Respawn();
|
||||
|
||||
if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_pSpecFlag)
|
||||
{
|
||||
if(m_pSpecFlag->GetCarrier())
|
||||
m_SpectatorID = m_pSpecFlag->GetCarrier()->GetPlayer()->GetCID();
|
||||
else
|
||||
m_SpectatorID = -1;
|
||||
}
|
||||
|
||||
if(m_pCharacter)
|
||||
{
|
||||
if(m_pCharacter->IsAlive())
|
||||
|
@ -113,8 +125,13 @@ void CPlayer::PostTick()
|
|||
}
|
||||
|
||||
// update view pos for spectators and dead players
|
||||
if((m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
|
||||
m_ViewPos = GameServer()->m_apPlayers[m_SpectatorID]->m_ViewPos;
|
||||
if((m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && m_SpecMode != SPEC_FREEVIEW)
|
||||
{
|
||||
if(m_pSpecFlag)
|
||||
m_ViewPos = m_pSpecFlag->GetPos();
|
||||
else if (GameServer()->m_apPlayers[m_SpectatorID])
|
||||
m_ViewPos = GameServer()->m_apPlayers[m_SpectatorID]->m_ViewPos;
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayer::Snap(int SnappingClient)
|
||||
|
@ -133,8 +150,9 @@ void CPlayer::Snap(int SnappingClient)
|
|||
pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_READY;
|
||||
if(m_RespawnDisabled && (!GetCharacter() || !GetCharacter()->IsAlive()))
|
||||
pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_DEAD;
|
||||
if(SnappingClient != -1 && (m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && SnappingClient == m_SpectatorID)
|
||||
if(SnappingClient != -1 && (m_Team == TEAM_SPECTATORS || m_DeadSpecMode) && (SnappingClient == m_SpectatorID))
|
||||
pPlayerInfo->m_PlayerFlags |= PLAYERFLAG_WATCHING;
|
||||
|
||||
pPlayerInfo->m_Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
|
||||
pPlayerInfo->m_Score = m_Score;
|
||||
|
||||
|
@ -144,9 +162,18 @@ void CPlayer::Snap(int SnappingClient)
|
|||
if(!pSpectatorInfo)
|
||||
return;
|
||||
|
||||
pSpectatorInfo->m_SpecMode = m_SpecMode;
|
||||
pSpectatorInfo->m_SpectatorID = m_SpectatorID;
|
||||
pSpectatorInfo->m_X = m_ViewPos.x;
|
||||
pSpectatorInfo->m_Y = m_ViewPos.y;
|
||||
if(m_pSpecFlag)
|
||||
{
|
||||
pSpectatorInfo->m_X = m_pSpecFlag->GetPos().x;
|
||||
pSpectatorInfo->m_Y = m_pSpecFlag->GetPos().y;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSpectatorInfo->m_X = m_ViewPos.x;
|
||||
pSpectatorInfo->m_Y = m_ViewPos.y;
|
||||
}
|
||||
}
|
||||
|
||||
// demo recording
|
||||
|
@ -180,12 +207,15 @@ void CPlayer::OnDisconnect()
|
|||
// update spectator modes
|
||||
for(int i = 0; i < MAX_CLIENTS; ++i)
|
||||
{
|
||||
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
|
||||
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpecMode == SPEC_PLAYER && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
|
||||
{
|
||||
if(GameServer()->m_apPlayers[i]->m_DeadSpecMode)
|
||||
GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
|
||||
else
|
||||
GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->m_SpecMode = SPEC_FREEVIEW;
|
||||
GameServer()->m_apPlayers[i]->m_SpectatorID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -220,7 +250,7 @@ void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
|
|||
m_pCharacter->ResetInput();
|
||||
|
||||
m_PlayerFlags = NewInput->m_PlayerFlags;
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
m_PlayerFlags = NewInput->m_PlayerFlags;
|
||||
|
@ -231,6 +261,42 @@ void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
|
|||
if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (NewInput->m_Fire&1))
|
||||
Respawn();
|
||||
|
||||
if(!m_pCharacter && m_Team == TEAM_SPECTATORS && (NewInput->m_Fire&1))
|
||||
{
|
||||
if(!m_ActiveSpecSwitch)
|
||||
{
|
||||
m_ActiveSpecSwitch = true;
|
||||
if(m_SpecMode == SPEC_FREEVIEW)
|
||||
{
|
||||
CCharacter *pChar = (CCharacter *)GameServer()->m_World.ClosestEntity(m_ViewPos, 6.0f*32, CGameWorld::ENTTYPE_CHARACTER, 0);
|
||||
CFlag *pFlag = (CFlag *)GameServer()->m_World.ClosestEntity(m_ViewPos, 6.0f*32, CGameWorld::ENTTYPE_FLAG, 0);
|
||||
if(pChar || pFlag)
|
||||
{
|
||||
if(!pChar || (pFlag && pChar && distance(m_ViewPos, pFlag->GetPos()) < distance(m_ViewPos, pChar->GetPos())))
|
||||
{
|
||||
m_SpecMode = pFlag->GetTeam() == TEAM_RED ? SPEC_FLAGRED : SPEC_FLAGBLUE;
|
||||
m_pSpecFlag = pFlag;
|
||||
m_SpectatorID = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SpecMode = SPEC_PLAYER;
|
||||
m_pSpecFlag = 0;
|
||||
m_SpectatorID = pChar->GetPlayer()->GetCID();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_SpecMode = SPEC_FREEVIEW;
|
||||
m_pSpecFlag = 0;
|
||||
m_SpectatorID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_ActiveSpecSwitch)
|
||||
m_ActiveSpecSwitch = false;
|
||||
|
||||
// check for activity
|
||||
if(NewInput->m_Direction || m_LatestActivity.m_TargetX != NewInput->m_TargetX ||
|
||||
m_LatestActivity.m_TargetY != NewInput->m_TargetY || NewInput->m_Jump ||
|
||||
|
@ -277,16 +343,40 @@ void CPlayer::Respawn()
|
|||
m_Spawning = true;
|
||||
}
|
||||
|
||||
bool CPlayer::SetSpectatorID(int SpectatorID)
|
||||
bool CPlayer::SetSpectatorID(int SpecMode, int SpectatorID)
|
||||
{
|
||||
if(m_SpectatorID == SpectatorID || m_ClientID == SpectatorID)
|
||||
if((SpecMode == SPEC_PLAYER && (SpectatorID == -1 || m_SpectatorID == SpectatorID || m_ClientID == SpectatorID)) ||
|
||||
(SpecMode != SPEC_PLAYER && SpecMode == m_SpecMode))
|
||||
return false;
|
||||
|
||||
if(m_Team == TEAM_SPECTATORS)
|
||||
{
|
||||
// check for freeview or if wanted player is playing
|
||||
if(SpectatorID == SPEC_FREEVIEW || (GameServer()->m_apPlayers[SpectatorID] && GameServer()->m_apPlayers[SpectatorID]->GetTeam() != TEAM_SPECTATORS))
|
||||
if(SpecMode != SPEC_PLAYER || (SpecMode == SPEC_PLAYER && GameServer()->m_apPlayers[SpectatorID] && GameServer()->m_apPlayers[SpectatorID]->GetTeam() != TEAM_SPECTATORS))
|
||||
{
|
||||
if(SpecMode == SPEC_FLAGRED || SpecMode == SPEC_FLAGBLUE)
|
||||
{
|
||||
CFlag *pFlag = (CFlag*)GameServer()->m_World.FindFirst(CGameWorld::ENTTYPE_FLAG);
|
||||
while (pFlag)
|
||||
{
|
||||
if ((pFlag->GetTeam() == TEAM_RED && SpecMode == SPEC_FLAGRED) || (pFlag->GetTeam() == TEAM_BLUE && SpecMode == SPEC_FLAGBLUE))
|
||||
{
|
||||
m_pSpecFlag = pFlag;
|
||||
if (pFlag->GetCarrier())
|
||||
m_SpectatorID = pFlag->GetCarrier()->GetPlayer()->GetCID();
|
||||
else
|
||||
m_SpectatorID = -1;
|
||||
break;
|
||||
}
|
||||
pFlag = (CFlag*)pFlag->TypeNext();
|
||||
}
|
||||
if (!m_pSpecFlag)
|
||||
return false;
|
||||
m_SpecMode = SpecMode;
|
||||
return true;
|
||||
}
|
||||
m_pSpecFlag = 0;
|
||||
m_SpecMode = SpecMode;
|
||||
m_SpectatorID = SpectatorID;
|
||||
return true;
|
||||
}
|
||||
|
@ -294,8 +384,10 @@ bool CPlayer::SetSpectatorID(int SpectatorID)
|
|||
else if(m_DeadSpecMode)
|
||||
{
|
||||
// check if wanted player can be followed
|
||||
if(GameServer()->m_apPlayers[SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[SpectatorID]))
|
||||
if(SpecMode == SPEC_PLAYER && GameServer()->m_apPlayers[SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[SpectatorID]))
|
||||
{
|
||||
m_SpecMode = SpecMode;
|
||||
m_pSpecFlag = 0;
|
||||
m_SpectatorID = SpectatorID;
|
||||
return true;
|
||||
}
|
||||
|
@ -313,7 +405,7 @@ bool CPlayer::DeadCanFollow(CPlayer *pPlayer) const
|
|||
void CPlayer::UpdateDeadSpecMode()
|
||||
{
|
||||
// check if actual spectator id is valid
|
||||
if(m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[m_SpectatorID]))
|
||||
if(m_SpecMode == SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID] && DeadCanFollow(GameServer()->m_apPlayers[m_SpectatorID]))
|
||||
return;
|
||||
|
||||
// find player to follow
|
||||
|
@ -336,23 +428,28 @@ void CPlayer::SetTeam(int Team, bool DoChatMsg)
|
|||
|
||||
m_Team = Team;
|
||||
m_LastActionTick = Server()->Tick();
|
||||
m_SpectatorID = SPEC_FREEVIEW;
|
||||
m_SpecMode = SPEC_FREEVIEW;
|
||||
m_SpectatorID = -1;
|
||||
m_pSpecFlag = 0;
|
||||
m_DeadSpecMode = false;
|
||||
|
||||
|
||||
// we got to wait 0.5 secs before respawning
|
||||
m_RespawnTick = Server()->Tick()+Server()->TickSpeed()/2;
|
||||
|
||||
|
||||
if(Team == TEAM_SPECTATORS)
|
||||
{
|
||||
// update spectator modes
|
||||
for(int i = 0; i < MAX_CLIENTS; ++i)
|
||||
{
|
||||
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
|
||||
if(GameServer()->m_apPlayers[i] && GameServer()-> m_apPlayers[i]->m_SpecMode == SPEC_PLAYER && GameServer()->m_apPlayers[i]->m_SpectatorID == m_ClientID)
|
||||
{
|
||||
if(GameServer()->m_apPlayers[i]->m_DeadSpecMode)
|
||||
GameServer()->m_apPlayers[i]->UpdateDeadSpecMode();
|
||||
else
|
||||
GameServer()->m_apPlayers[i]->m_SpectatorID = SPEC_FREEVIEW;
|
||||
{
|
||||
GameServer()->m_apPlayers[i]->m_SpecMode = SPEC_FREEVIEW;
|
||||
GameServer()->m_apPlayers[i]->m_SpectatorID = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public:
|
|||
|
||||
// used for spectator mode
|
||||
int GetSpectatorID() const { return m_SpectatorID; }
|
||||
bool SetSpectatorID(int SpectatorID);
|
||||
bool SetSpectatorID(int SpecMode, int SpectatorID);
|
||||
bool m_DeadSpecMode;
|
||||
bool DeadCanFollow(CPlayer *pPlayer) const;
|
||||
void UpdateDeadSpecMode();
|
||||
|
@ -126,7 +126,10 @@ private:
|
|||
bool m_Dummy;
|
||||
|
||||
// used for spectator mode
|
||||
int m_SpecMode;
|
||||
int m_SpectatorID;
|
||||
class CFlag *m_pSpecFlag;
|
||||
bool m_ActiveSpecSwitch;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue