2010-11-20 10:37:14 +00:00
|
|
|
/* (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. */
|
2010-05-29 07:25:38 +00:00
|
|
|
#include <engine/shared/config.h>
|
|
|
|
|
|
|
|
#include <game/generated/protocol.h>
|
|
|
|
#include <base/vmath.h>
|
|
|
|
#include <game/client/render.h>
|
|
|
|
//#include <game/client/gameclient.h>
|
|
|
|
#include "voting.h"
|
|
|
|
|
|
|
|
void CVoting::ConCallvote(IConsole::IResult *pResult, void *pUserData)
|
|
|
|
{
|
|
|
|
CVoting *pSelf = (CVoting*)pUserData;
|
|
|
|
pSelf->Callvote(pResult->GetString(0), pResult->GetString(1));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CVoting::ConVote(IConsole::IResult *pResult, void *pUserData)
|
|
|
|
{
|
|
|
|
CVoting *pSelf = (CVoting *)pUserData;
|
|
|
|
if(str_comp_nocase(pResult->GetString(0), "yes") == 0)
|
|
|
|
pSelf->Vote(1);
|
|
|
|
else if(str_comp_nocase(pResult->GetString(0), "no") == 0)
|
|
|
|
pSelf->Vote(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CVoting::Callvote(const char *pType, const char *pValue)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Cl_CallVote Msg = {0};
|
|
|
|
Msg.m_Type = pType;
|
|
|
|
Msg.m_Value = pValue;
|
|
|
|
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
void CVoting::CallvoteKick(int ClientID, const char *pReason)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-10-09 18:34:17 +00:00
|
|
|
char aBuf[32];
|
|
|
|
if(pReason[0])
|
2011-02-12 10:40:36 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "%d %s", ClientID, pReason);
|
2010-10-09 18:34:17 +00:00
|
|
|
else
|
2011-02-12 10:40:36 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "%d", ClientID);
|
2010-10-09 18:34:17 +00:00
|
|
|
Callvote("kick", aBuf);
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
2008-09-25 12:23:44 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::CallvoteOption(int OptionId)
|
2008-09-29 11:34:49 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CVoteOption *pOption = m_pFirst;
|
|
|
|
while(pOption && OptionId >= 0)
|
|
|
|
{
|
|
|
|
if(OptionId == 0)
|
|
|
|
{
|
|
|
|
Callvote("option", pOption->m_aCommand);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
OptionId--;
|
|
|
|
pOption = pOption->m_pNext;
|
|
|
|
}
|
2008-09-29 11:34:49 +00:00
|
|
|
}
|
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
void CVoting::ForcevoteKick(int ClientID, const char *pReason)
|
2008-09-29 11:34:49 +00:00
|
|
|
{
|
2010-10-10 23:06:44 +00:00
|
|
|
char aBuf[32];
|
|
|
|
if(pReason[0])
|
2011-02-12 10:40:36 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "kick %d %s", ClientID, pReason);
|
2010-10-10 23:06:44 +00:00
|
|
|
else
|
2011-02-12 10:40:36 +00:00
|
|
|
str_format(aBuf, sizeof(aBuf), "kick %d", ClientID);
|
2010-10-10 23:06:44 +00:00
|
|
|
Client()->Rcon(aBuf);
|
2008-09-29 11:34:49 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::ForcevoteOption(int OptionId)
|
2008-09-29 11:34:49 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CVoteOption *pOption = m_pFirst;
|
|
|
|
while(pOption && OptionId >= 0)
|
2008-11-08 12:50:46 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(OptionId == 0)
|
2008-11-08 12:50:46 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Client()->Rcon(pOption->m_aCommand);
|
2008-11-08 12:50:46 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
OptionId--;
|
|
|
|
pOption = pOption->m_pNext;
|
2008-11-08 12:50:46 +00:00
|
|
|
}
|
2008-09-29 11:34:49 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::Vote(int v)
|
2008-09-25 12:23:44 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Cl_Vote Msg = {v};
|
|
|
|
Client()->SendPackMsg(&Msg, MSGFLAG_VITAL);
|
2008-09-25 12:23:44 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CVoting::CVoting()
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
ClearOptions();
|
|
|
|
OnReset();
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
|
2008-11-08 12:50:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::ClearOptions()
|
2008-11-08 12:50:46 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Heap.Reset();
|
2008-11-08 12:50:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
m_pFirst = 0;
|
|
|
|
m_pLast = 0;
|
2008-11-08 12:50:46 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::OnReset()
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
m_Closetime = 0;
|
|
|
|
m_aDescription[0] = 0;
|
|
|
|
m_aCommand[0] = 0;
|
|
|
|
m_Yes = m_No = m_Pass = m_Total = 0;
|
|
|
|
m_Voted = 0;
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::OnConsoleInit()
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
Console()->Register("callvote", "sr", CFGFLAG_CLIENT, ConCallvote, this, "Call vote");
|
|
|
|
Console()->Register("vote", "r", CFGFLAG_CLIENT, ConVote, this, "Vote yes/no");
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::OnMessage(int MsgType, void *pRawMsg)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
if(MsgType == NETMSGTYPE_SV_VOTESET)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Sv_VoteSet *pMsg = (CNetMsg_Sv_VoteSet *)pRawMsg;
|
|
|
|
if(pMsg->m_Timeout)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
OnReset();
|
|
|
|
str_copy(m_aDescription, pMsg->m_pDescription, sizeof(m_aDescription));
|
|
|
|
str_copy(m_aCommand, pMsg->m_pCommand, sizeof(m_aCommand));
|
|
|
|
m_Closetime = time_get() + time_freq() * pMsg->m_Timeout;
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
else
|
2010-05-29 07:25:38 +00:00
|
|
|
OnReset();
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(MsgType == NETMSGTYPE_SV_VOTESTATUS)
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Sv_VoteStatus *pMsg = (CNetMsg_Sv_VoteStatus *)pRawMsg;
|
|
|
|
m_Yes = pMsg->m_Yes;
|
|
|
|
m_No = pMsg->m_No;
|
|
|
|
m_Pass = pMsg->m_Pass;
|
|
|
|
m_Total = pMsg->m_Total;
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(MsgType == NETMSGTYPE_SV_VOTECLEAROPTIONS)
|
2008-11-08 12:50:46 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
ClearOptions();
|
2008-11-08 12:50:46 +00:00
|
|
|
}
|
2010-05-29 07:25:38 +00:00
|
|
|
else if(MsgType == NETMSGTYPE_SV_VOTEOPTION)
|
2008-11-08 12:50:46 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CNetMsg_Sv_VoteOption *pMsg = (CNetMsg_Sv_VoteOption *)pRawMsg;
|
|
|
|
int Len = str_length(pMsg->m_pCommand);
|
2008-11-08 12:50:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CVoteOption *pOption = (CVoteOption *)m_Heap.Allocate(sizeof(CVoteOption) + Len);
|
|
|
|
pOption->m_pNext = 0;
|
|
|
|
pOption->m_pPrev = m_pLast;
|
|
|
|
if(pOption->m_pPrev)
|
|
|
|
pOption->m_pPrev->m_pNext = pOption;
|
|
|
|
m_pLast = pOption;
|
|
|
|
if(!m_pFirst)
|
|
|
|
m_pFirst = pOption;
|
2008-11-08 12:50:46 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
mem_copy(pOption->m_aCommand, pMsg->m_pCommand, Len+1);
|
2008-11-08 12:50:46 +00:00
|
|
|
|
|
|
|
}
|
2008-09-24 14:47:03 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::OnRender()
|
2008-09-24 14:47:03 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2008-09-25 14:04:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
void CVoting::RenderBars(CUIRect Bars, bool Text)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
RenderTools()->DrawUIRect(&Bars, vec4(0.8f,0.8f,0.8f,0.5f), CUI::CORNER_ALL, Bars.h/3);
|
2008-09-25 14:04:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
CUIRect Splitter = Bars;
|
|
|
|
Splitter.x = Splitter.x+Splitter.w/2;
|
|
|
|
Splitter.w = Splitter.h/2.0f;
|
|
|
|
Splitter.x -= Splitter.w/2;
|
|
|
|
RenderTools()->DrawUIRect(&Splitter, vec4(0.4f,0.4f,0.4f,0.5f), CUI::CORNER_ALL, Splitter.h/4);
|
2008-09-25 14:04:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_Total)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CUIRect PassArea = Bars;
|
|
|
|
if(m_Yes)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CUIRect YesArea = Bars;
|
|
|
|
YesArea.w *= m_Yes/(float)m_Total;
|
|
|
|
RenderTools()->DrawUIRect(&YesArea, vec4(0.2f,0.9f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3);
|
2008-09-25 14:04:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Text)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
char Buf[256];
|
|
|
|
str_format(Buf, sizeof(Buf), "%d", m_Yes);
|
|
|
|
UI()->DoLabel(&YesArea, Buf, Bars.h*0.75f, 0);
|
2008-09-25 14:04:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
PassArea.x += YesArea.w;
|
|
|
|
PassArea.w -= YesArea.w;
|
2008-09-25 14:04:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(m_No)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
CUIRect NoArea = Bars;
|
|
|
|
NoArea.w *= m_No/(float)m_Total;
|
|
|
|
NoArea.x = (Bars.x + Bars.w)-NoArea.w;
|
|
|
|
RenderTools()->DrawUIRect(&NoArea, vec4(0.9f,0.2f,0.2f,0.85f), CUI::CORNER_ALL, Bars.h/3);
|
2008-09-25 14:04:02 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Text)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
char Buf[256];
|
|
|
|
str_format(Buf, sizeof(Buf), "%d", m_No);
|
|
|
|
UI()->DoLabel(&NoArea, Buf, Bars.h*0.75f, 0);
|
2008-09-25 14:04:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
PassArea.w -= NoArea.w;
|
2008-09-25 14:04:02 +00:00
|
|
|
}
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(Text && m_Pass)
|
2008-09-25 14:04:02 +00:00
|
|
|
{
|
2010-05-29 07:25:38 +00:00
|
|
|
char Buf[256];
|
|
|
|
str_format(Buf, sizeof(Buf), "%d", m_Pass);
|
|
|
|
UI()->DoLabel(&PassArea, Buf, Bars.h*0.75f, 0);
|
2008-09-25 14:04:02 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|