mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-19 14:38:18 +00:00
added support for ai-controlled players #1390
This commit is contained in:
parent
454af88ee5
commit
75350af11d
|
@ -6,7 +6,7 @@ Emoticons = Enum("EMOTICON", ["OOP", "EXCLAMATION", "HEARTS", "DROP", "DOTDOT",
|
|||
Votes = Enum("VOTE", ["UNKNOWN", "START_OP", "START_KICK", "START_SPEC", "END_ABORT", "END_PASS", "END_FAIL"])
|
||||
ChatModes = Enum("CHAT", ["NONE", "ALL", "TEAM", "WHISPER"])
|
||||
|
||||
PlayerFlags = Flags("PLAYERFLAG", ["ADMIN", "CHATTING", "SCOREBOARD", "READY", "DEAD", "WATCHING"])
|
||||
PlayerFlags = Flags("PLAYERFLAG", ["ADMIN", "CHATTING", "SCOREBOARD", "READY", "DEAD", "WATCHING", "BOT"])
|
||||
GameFlags = Flags("GAMEFLAG", ["TEAMS", "FLAGS", "SURVIVAL"])
|
||||
GameStateFlags = Flags("GAMESTATEFLAG", ["WARMUP", "SUDDENDEATH", "ROUNDOVER", "GAMEOVER", "PAUSED", "STARTCOUNTDOWN"])
|
||||
CoreEventFlags = Flags("COREEVENTFLAG", ["GROUND_JUMP", "AIR_JUMP", "HOOK_ATTACH_PLAYER", "HOOK_ATTACH_GROUND", "HOOK_HIT_NOHOOK"])
|
||||
|
|
|
@ -828,9 +828,9 @@ int CClient::PlayerScoreComp(const void *a, const void *b)
|
|||
{
|
||||
CServerInfo::CClient *p0 = (CServerInfo::CClient *)a;
|
||||
CServerInfo::CClient *p1 = (CServerInfo::CClient *)b;
|
||||
if(p0->m_Player && !p1->m_Player)
|
||||
if(!(p0->m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC) && (p1->m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC))
|
||||
return -1;
|
||||
if(!p0->m_Player && p1->m_Player)
|
||||
if((p0->m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC) && !(p1->m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC))
|
||||
return 1;
|
||||
if(p0->m_Score == p1->m_Score)
|
||||
return 0;
|
||||
|
@ -857,6 +857,8 @@ int CClient::UnpackServerInfo(CUnpacker *pUnpacker, CServerInfo *pInfo, int *pTo
|
|||
pInfo->m_MaxPlayers = pUnpacker->GetInt();
|
||||
pInfo->m_NumClients = pUnpacker->GetInt();
|
||||
pInfo->m_MaxClients = pUnpacker->GetInt();
|
||||
pInfo->m_NumBotPlayers = 0;
|
||||
pInfo->m_NumBotSpectators = 0;
|
||||
|
||||
// don't add invalid info to the server browser list
|
||||
if(pInfo->m_NumClients < 0 || pInfo->m_NumClients > MAX_CLIENTS || pInfo->m_MaxClients < 0 || pInfo->m_MaxClients > MAX_CLIENTS ||
|
||||
|
@ -867,15 +869,31 @@ int CClient::UnpackServerInfo(CUnpacker *pUnpacker, CServerInfo *pInfo, int *pTo
|
|||
if(!pToken)
|
||||
return 0;
|
||||
|
||||
int NumPlayers = 0;
|
||||
int NumClients = 0;
|
||||
for(int i = 0; i < pInfo->m_NumClients; i++)
|
||||
{
|
||||
str_copy(pInfo->m_aClients[i].m_aName, pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(pInfo->m_aClients[i].m_aName));
|
||||
str_copy(pInfo->m_aClients[i].m_aClan, pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES), sizeof(pInfo->m_aClients[i].m_aClan));
|
||||
pInfo->m_aClients[i].m_Country = pUnpacker->GetInt();
|
||||
pInfo->m_aClients[i].m_Score = pUnpacker->GetInt();
|
||||
pInfo->m_aClients[i].m_Player = pUnpacker->GetInt() != 0 ? true : false;
|
||||
pInfo->m_aClients[i].m_PlayerType = pUnpacker->GetInt()&CServerInfo::CClient::PLAYERFLAG_MASK;
|
||||
|
||||
if(pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_BOT)
|
||||
{
|
||||
if(pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC)
|
||||
pInfo->m_NumBotSpectators++;
|
||||
else
|
||||
pInfo->m_NumBotPlayers++;
|
||||
}
|
||||
|
||||
NumClients++;
|
||||
if(!(pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC))
|
||||
NumPlayers++;
|
||||
}
|
||||
pInfo->m_NumPlayers = NumPlayers;
|
||||
pInfo->m_NumClients = NumClients;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ void CServerBrowser::CServerlist::Clear()
|
|||
m_ServerlistHeap.Reset();
|
||||
m_NumServers = 0;
|
||||
m_NumPlayers = 0;
|
||||
m_NumClients = 0;
|
||||
mem_zero(m_aServerlistIp, sizeof(m_aServerlistIp));
|
||||
}
|
||||
|
||||
|
@ -545,6 +546,7 @@ void CServerBrowser::SetInfo(int ServerlistType, CServerEntry *pEntry, const CSe
|
|||
pEntry->m_Info.m_NetAddr = pEntry->m_Addr;
|
||||
|
||||
m_aServerlist[ServerlistType].m_NumPlayers += pEntry->m_Info.m_NumPlayers;
|
||||
m_aServerlist[ServerlistType].m_NumClients += pEntry->m_Info.m_NumClients;
|
||||
|
||||
pEntry->m_InfoState = CServerEntry::STATE_READY;
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
|
||||
int NumServers() const { return m_aServerlist[m_ActServerlistType].m_NumServers; }
|
||||
int NumPlayers() const { return m_aServerlist[m_ActServerlistType].m_NumPlayers; }
|
||||
int NumClients() const { return m_aServerlist[m_ActServerlistType].m_NumClients; }
|
||||
const CServerInfo *Get(int Index) const { return &m_aServerlist[m_ActServerlistType].m_ppServerlist[Index]->m_Info; };
|
||||
|
||||
int NumSortedServers(int FilterIndex) const { return m_ServerBrowserFilter.GetNumSortedServers(FilterIndex); }
|
||||
|
@ -72,6 +73,7 @@ private:
|
|||
public:
|
||||
class CHeap m_ServerlistHeap;
|
||||
|
||||
int m_NumClients;
|
||||
int m_NumPlayers;
|
||||
int m_NumServers;
|
||||
int m_NumServerCapacity;
|
||||
|
|
|
@ -201,7 +201,15 @@ void CServerBrowserFilter::CServerFilter::Filter()
|
|||
if(!(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_FRIENDS) || m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_FriendState != IFriends::FRIEND_NO)
|
||||
{
|
||||
m_pSortedServerlist[m_NumSortedServers++] = i;
|
||||
m_NumSortedPlayers += (m_FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS) ? m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumPlayers : m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumClients;
|
||||
|
||||
int Count = (m_FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS) ? m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumPlayers : m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumClients;
|
||||
if(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_BOTS)
|
||||
{
|
||||
Count -= m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumBotPlayers;
|
||||
if(!(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS))
|
||||
Count -= m_pServerBrowserFilter->m_ppServerlist[i]->m_Info.m_NumBotSpectators;
|
||||
}
|
||||
m_NumSortedPlayers += Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -209,8 +217,9 @@ void CServerBrowserFilter::CServerFilter::Filter()
|
|||
|
||||
int CServerBrowserFilter::CServerFilter::GetSortHash() const
|
||||
{
|
||||
int i = g_Config.m_BrSort&0xf;
|
||||
i |= g_Config.m_BrSortOrder<<4;
|
||||
int i = g_Config.m_BrSort&0x7;
|
||||
i |= g_Config.m_BrSortOrder<<3;
|
||||
if(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_BOTS) i |= 1 << 4;
|
||||
if(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_EMPTY) i |= 1<<5;
|
||||
if(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_FULL) i |= 1<<6;
|
||||
if(m_FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS) i |= 1<<7;
|
||||
|
|
|
@ -1100,7 +1100,7 @@ void CServer::GenerateServerInfo(CPacker *pPacker, int Token)
|
|||
pPacker->AddString(ClientClan(i), MAX_CLAN_LENGTH); // client clan
|
||||
pPacker->AddInt(m_aClients[i].m_Country); // client country
|
||||
pPacker->AddInt(m_aClients[i].m_Score); // client score
|
||||
pPacker->AddInt(GameServer()->IsClientPlayer(i)?1:0); // is player?
|
||||
pPacker->AddInt(GameServer()->IsClientPlayer(i)?0:1); // flag spectator=1, bot=2 (player=0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,9 +23,16 @@ public:
|
|||
char m_aClan[MAX_CLAN_LENGTH];
|
||||
int m_Country;
|
||||
int m_Score;
|
||||
bool m_Player;
|
||||
int m_PlayerType;
|
||||
|
||||
int m_FriendState;
|
||||
|
||||
enum
|
||||
{
|
||||
PLAYERFLAG_SPEC=1,
|
||||
PLAYERFLAG_BOT=2,
|
||||
PLAYERFLAG_MASK=3,
|
||||
};
|
||||
};
|
||||
|
||||
//int m_SortedIndex;
|
||||
|
@ -40,6 +47,8 @@ public:
|
|||
int m_NumClients;
|
||||
int m_MaxPlayers;
|
||||
int m_NumPlayers;
|
||||
int m_NumBotPlayers;
|
||||
int m_NumBotSpectators;
|
||||
int m_Flags;
|
||||
int m_ServerLevel;
|
||||
int m_Favorite;
|
||||
|
@ -102,6 +111,7 @@ public:
|
|||
FLAG_PURE=2,
|
||||
FLAG_PUREMAP=4,
|
||||
|
||||
FILTER_BOTS=16,
|
||||
FILTER_EMPTY=32,
|
||||
FILTER_FULL=64,
|
||||
FILTER_SPECTATORS=128,
|
||||
|
@ -123,6 +133,7 @@ public:
|
|||
|
||||
virtual int NumServers() const = 0;
|
||||
virtual int NumPlayers() const = 0;
|
||||
virtual int NumClients() const = 0;
|
||||
virtual const CServerInfo *Get(int Index) const = 0;
|
||||
|
||||
virtual int NumSortedServers(int Index) const = 0;
|
||||
|
|
|
@ -507,10 +507,26 @@ int CMenus::DoBrowserEntry(const void *pID, CUIRect View, const CServerInfo *pEn
|
|||
CServerFilterInfo FilterInfo;
|
||||
pFilter->GetFilter(&FilterInfo);
|
||||
|
||||
int Num = (FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS) ? pEntry->m_NumPlayers : pEntry->m_NumClients;
|
||||
int Max = (FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS) ? pEntry->m_MaxPlayers : pEntry->m_MaxClients;
|
||||
if(FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS)
|
||||
str_format(aTemp, sizeof(aTemp), "%d/%d", pEntry->m_NumPlayers, pEntry->m_MaxPlayers);
|
||||
else
|
||||
str_format(aTemp, sizeof(aTemp), "%d/%d", pEntry->m_NumClients, pEntry->m_MaxClients);
|
||||
{
|
||||
int SpecNum = pEntry->m_NumClients - pEntry->m_NumPlayers;
|
||||
if(pEntry->m_MaxClients - pEntry->m_MaxPlayers < SpecNum)
|
||||
Max -= SpecNum;
|
||||
}
|
||||
if(FilterInfo.m_SortHash&IServerBrowser::FILTER_BOTS)
|
||||
{
|
||||
Num -= pEntry->m_NumBotPlayers;
|
||||
Max -= pEntry->m_NumBotPlayers;
|
||||
if(!(FilterInfo.m_SortHash&IServerBrowser::FILTER_SPECTATORS))
|
||||
{
|
||||
Num -= pEntry->m_NumBotSpectators;
|
||||
Max -= pEntry->m_NumBotSpectators;
|
||||
}
|
||||
|
||||
}
|
||||
str_format(aTemp, sizeof(aTemp), "%d/%d", Num, Max);
|
||||
if(g_Config.m_BrFilterString[0] && (pEntry->m_QuickSearchHit&IServerBrowser::QUICK_PLAYER))
|
||||
TextRender()->TextColor(0.4f, 0.4f, 1.0f, TextAlpha);
|
||||
Button.y += 2.0f;
|
||||
|
@ -797,7 +813,7 @@ void CMenus::RenderServerbrowserOverlay()
|
|||
Name.VSplitRight(40.0f, &Name, &Clan);
|
||||
|
||||
// score
|
||||
if(pInfo->m_aClients[i].m_Player)
|
||||
if(!(pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC))
|
||||
{
|
||||
char aTemp[16];
|
||||
str_format(aTemp, sizeof(aTemp), "%d", pInfo->m_aClients[i].m_Score);
|
||||
|
@ -1141,7 +1157,7 @@ void CMenus::RenderServerbrowserServerList(CUIRect View)
|
|||
CUIRect OriginalView = View;
|
||||
View.y -= s_ScrollValue*ScrollNum*LineH;
|
||||
|
||||
int NumPlayers = ServerBrowser()->NumPlayers();
|
||||
int NumPlayers = ServerBrowser()->NumClients();
|
||||
|
||||
for(int s = 0; s < m_lFilters.size(); s++)
|
||||
{
|
||||
|
@ -1362,7 +1378,7 @@ void CMenus::RenderServerbrowserFriendTab(CUIRect View)
|
|||
FriendItem.m_pServerInfo = pEntry;
|
||||
str_copy(FriendItem.m_aName, pEntry->m_aClients[j].m_aName, sizeof(FriendItem.m_aName));
|
||||
str_copy(FriendItem.m_aClan, pEntry->m_aClients[j].m_aClan, sizeof(FriendItem.m_aClan));
|
||||
FriendItem.m_IsPlayer = pEntry->m_aClients[j].m_Player;
|
||||
FriendItem.m_IsPlayer = !(pEntry->m_aClients[j].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC);
|
||||
|
||||
if(pEntry->m_aClients[j].m_FriendState == IFriends::FRIEND_PLAYER)
|
||||
m_lFriendList[0].add(FriendItem);
|
||||
|
@ -1596,6 +1612,11 @@ void CMenus::RenderServerbrowserFilterTab(CUIRect View)
|
|||
if(DoButton_CheckBox(&s_BrFilterFriends, Localize("Show friends only"), FilterInfo.m_SortHash&IServerBrowser::FILTER_FRIENDS, &Button))
|
||||
NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_FRIENDS;
|
||||
|
||||
ServerFilter.HSplitTop(LineSize, &Button, &ServerFilter);
|
||||
static int s_BrFilterBots = 0;
|
||||
if(DoButton_CheckBox(&s_BrFilterBots, Localize("Hide Bots"), FilterInfo.m_SortHash&IServerBrowser::FILTER_BOTS, &Button))
|
||||
NewSortHash = FilterInfo.m_SortHash^IServerBrowser::FILTER_BOTS;
|
||||
|
||||
ServerFilter.HSplitTop(LineSize, &Button, &ServerFilter);
|
||||
static int s_BrFilterPw = 0;
|
||||
if(DoButton_CheckBox(&s_BrFilterPw, Localize("No password"), FilterInfo.m_SortHash&IServerBrowser::FILTER_PW, &Button))
|
||||
|
@ -1900,8 +1921,23 @@ void CMenus::RenderDetailInfo(CUIRect View, const CServerInfo *pInfo)
|
|||
|
||||
void CMenus::RenderDetailScoreboard(CUIRect View, const CServerInfo *pInfo, int Column)
|
||||
{
|
||||
// slected filter
|
||||
CBrowserFilter *pFilter = 0;
|
||||
for(int i = 0; i < m_lFilters.size(); ++i)
|
||||
{
|
||||
if(m_lFilters[i].Extended())
|
||||
{
|
||||
pFilter = &m_lFilters[i];
|
||||
m_SelectedFilter = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!pFilter)
|
||||
return;
|
||||
CServerFilterInfo FilterInfo;
|
||||
pFilter->GetFilter(&FilterInfo);
|
||||
|
||||
// server scoreboard
|
||||
// CUIRect ServerHeader;
|
||||
CTextCursor Cursor;
|
||||
const float FontSize = 10.0f;
|
||||
int ActColumn = 0;
|
||||
|
@ -1911,17 +1947,21 @@ void CMenus::RenderDetailScoreboard(CUIRect View, const CServerInfo *pInfo, int
|
|||
if(pInfo)
|
||||
{
|
||||
CUIRect Row = View;
|
||||
int Count = 0;
|
||||
for(int i = 0; i < pInfo->m_NumClients; i++)
|
||||
{
|
||||
if((FilterInfo.m_SortHash&IServerBrowser::FILTER_BOTS) && (pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_BOT))
|
||||
continue;
|
||||
|
||||
CUIRect Name, Clan, Score, Flag, Icon;
|
||||
if(i % (16 / Column) == 0)
|
||||
if(Count % (16 / Column) == 0)
|
||||
{
|
||||
View.VSplitLeft(View.w / (Column - ActColumn), &Row, &View);
|
||||
ActColumn++;
|
||||
}
|
||||
|
||||
Row.HSplitTop(20.0f, &Name, &Row);
|
||||
RenderTools()->DrawUIRect(&Name, vec4(1.0f, 1.0f, 1.0f, (i % 2 + 1)*0.05f), CUI::CORNER_ALL, 4.0f);
|
||||
RenderTools()->DrawUIRect(&Name, vec4(1.0f, 1.0f, 1.0f, (Count % 2 + 1)*0.05f), CUI::CORNER_ALL, 4.0f);
|
||||
|
||||
// friend
|
||||
if(UI()->DoButtonLogic(&pInfo->m_aClients[i], "", 0, &Name))
|
||||
|
@ -1945,7 +1985,7 @@ void CMenus::RenderDetailScoreboard(CUIRect View, const CServerInfo *pInfo, int
|
|||
Name.HSplitTop(10.0f, &Name, &Clan);
|
||||
|
||||
// score
|
||||
if(pInfo->m_aClients[i].m_Player)
|
||||
if(!(pInfo->m_aClients[i].m_PlayerType&CServerInfo::CClient::PLAYERFLAG_SPEC))
|
||||
{
|
||||
char aTemp[16];
|
||||
str_format(aTemp, sizeof(aTemp), "%d", pInfo->m_aClients[i].m_Score);
|
||||
|
@ -2002,6 +2042,8 @@ void CMenus::RenderDetailScoreboard(CUIRect View, const CServerInfo *pInfo, int
|
|||
Flag.w = Flag.h*2;
|
||||
vec4 Color(1.0f, 1.0f, 1.0f, 0.5f);
|
||||
m_pClient->m_pCountryFlags->Render(pInfo->m_aClients[i].m_Country, &Color, Flag.x, Flag.y, Flag.w, Flag.h);
|
||||
|
||||
++Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue