dvander@780: /** dvander@780: * vim: set ts=4 : dvander@780: * =============================================================== dvander@780: * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. dvander@780: * =============================================================== dvander@780: * dvander@780: * This file is not open source and may not be copied without explicit dvander@780: * written permission of AlliedModders LLC. This file may not be redistributed dvander@780: * in whole or significant part. dvander@780: * For information, see LICENSE.txt or http://www.sourcemod.net/license.php dvander@780: * dvander@780: * Version: $Id$ dvander@780: */ dvander@780: dvander@780: #include "MenuStyle_Radio.h" dvander@780: #include "sm_stringutil.h" dvander@780: #include "UserMessages.h" dvander@780: #include "GameConfigs.h" dvander@846: #include "PlayerManager.h" dvander@780: dvander@780: extern const char *g_RadioNumTable[]; dvander@780: CRadioStyle g_RadioMenuStyle; dvander@780: int g_ShowMenuId = -1; dvander@785: bool g_bRadioInit = false; dvander@780: dvander@780: CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1]) dvander@780: { dvander@780: } dvander@780: dvander@846: void CRadioStyle::OnSourceModAllInitialized() dvander@846: { dvander@846: g_Players.AddClientListener(this); dvander@846: } dvander@846: dvander@785: void CRadioStyle::OnSourceModLevelChange(const char *mapName) dvander@780: { dvander@785: if (g_bRadioInit) dvander@785: { dvander@785: return; dvander@785: } dvander@785: dvander@785: g_bRadioInit = true; dvander@780: const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg"); dvander@780: if (!msg || msg[0] == '\0') dvander@780: { dvander@780: return; dvander@780: } dvander@780: dvander@780: g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg); dvander@780: dvander@780: if (!IsSupported()) dvander@780: { dvander@780: return; dvander@780: } dvander@780: dvander@780: g_Menus.AddStyle(this); dvander@780: g_Menus.SetDefaultStyle(this); dvander@780: dvander@780: g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false); dvander@780: } dvander@780: dvander@780: void CRadioStyle::OnSourceModShutdown() dvander@780: { dvander@846: g_Players.RemoveClientListener(this); dvander@780: g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false); dvander@790: dvander@790: while (!m_FreeDisplays.empty()) dvander@790: { dvander@790: delete m_FreeDisplays.front(); dvander@790: m_FreeDisplays.pop(); dvander@790: } dvander@780: } dvander@780: dvander@780: bool CRadioStyle::IsSupported() dvander@780: { dvander@780: return (g_ShowMenuId != -1); dvander@780: } dvander@780: dvander@780: bool CRadioStyle::OnClientCommand(int client) dvander@780: { dvander@780: const char *cmd = engine->Cmd_Argv(0); dvander@780: dvander@780: if (strcmp(cmd, "menuselect") == 0) dvander@780: { dvander@780: if (!m_players[client].bInMenu) dvander@780: { dvander@780: return false; dvander@780: } dvander@785: dvander@780: int arg = atoi(engine->Cmd_Argv(1)); dvander@780: ClientPressedKey(client, arg); dvander@785: return true; dvander@780: } dvander@780: dvander@780: return false; dvander@780: } dvander@780: dvander@780: static unsigned int g_last_holdtime = 0; dvander@780: static unsigned int g_last_client_count = 0; dvander@780: static int g_last_clients[256]; dvander@780: dvander@780: void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter) dvander@780: { dvander@780: int count = pFilter->GetRecipientCount(); dvander@780: bf_read br(bf->GetBasePointer(), 2); dvander@780: dvander@780: br.ReadWord(); dvander@780: int c = br.ReadChar(); dvander@780: dvander@780: g_last_holdtime = (c == -1) ? 0 : (unsigned)c; dvander@780: dvander@780: for (int i=0; iGetRecipientIndex(i); dvander@780: } dvander@780: } dvander@780: dvander@780: void CRadioStyle::OnUserMessageSent(int msg_id) dvander@780: { dvander@780: for (unsigned int i=0; iSendRawDisplay(client, m_players[client].menuHoldTime); dvander@780: } dvander@780: dvander@787: IMenuPanel *CRadioStyle::CreatePanel() dvander@780: { dvander@790: return g_RadioMenuStyle.MakeRadioDisplay(); dvander@780: } dvander@780: dvander@790: IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) dvander@780: { dvander@790: return new CRadioMenu(pHandler, pOwner); dvander@780: } dvander@780: dvander@780: unsigned int CRadioStyle::GetMaxPageItems() dvander@780: { dvander@780: return 10; dvander@780: } dvander@780: dvander@780: const char *CRadioStyle::GetStyleName() dvander@780: { dvander@780: return "radio"; dvander@780: } dvander@780: dvander@780: CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client) dvander@780: { dvander@780: return &m_players[client]; dvander@780: } dvander@780: dvander@790: CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu) dvander@790: { dvander@790: CRadioDisplay *display; dvander@790: if (m_FreeDisplays.empty()) dvander@790: { dvander@790: display = new CRadioDisplay(); dvander@790: } else { dvander@790: display = m_FreeDisplays.front(); dvander@790: m_FreeDisplays.pop(); dvander@790: display->Reset(); dvander@790: } dvander@790: return display; dvander@790: } dvander@790: dvander@790: void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display) dvander@790: { dvander@790: m_FreeDisplays.push(display); dvander@790: } dvander@790: dvander@780: CRadioDisplay::CRadioDisplay() dvander@780: { dvander@780: Reset(); dvander@780: } dvander@780: dvander@780: CRadioDisplay::CRadioDisplay(CRadioMenu *menu) dvander@780: { dvander@780: Reset(); dvander@780: } dvander@780: dvander@780: bool CRadioDisplay::DrawRawLine(const char *rawline) dvander@780: { dvander@780: m_BufferText.append(rawline); dvander@780: m_BufferText.append("\n"); dvander@780: return true; dvander@780: } dvander@780: dvander@780: void CRadioDisplay::Reset() dvander@780: { dvander@780: m_BufferText.assign(""); dvander@780: m_Title.assign(""); dvander@780: m_NextPos = 1; dvander@785: keys = 0; dvander@780: } dvander@780: dvander@840: unsigned int CRadioDisplay::GetCurrentKey() dvander@840: { dvander@840: return m_NextPos; dvander@840: } dvander@840: dvander@840: bool CRadioDisplay::SetCurrentKey(unsigned int key) dvander@840: { dvander@840: if (key < m_NextPos || m_NextPos > 10) dvander@840: { dvander@840: return false; dvander@840: } dvander@840: dvander@840: m_NextPos = key; dvander@840: dvander@840: return true; dvander@840: } dvander@840: dvander@780: bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time) dvander@780: { dvander@780: return g_RadioMenuStyle.DoClientMenu(client, this, handler, time); dvander@780: } dvander@780: dvander@780: bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr) dvander@780: { dvander@780: return false; dvander@780: } dvander@780: dvander@780: IMenuStyle *CRadioDisplay::GetParentStyle() dvander@780: { dvander@780: return &g_RadioMenuStyle; dvander@780: } dvander@780: dvander@780: void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */) dvander@780: { dvander@780: if (m_Title.size() != 0 && onlyIfEmpty) dvander@780: { dvander@780: return; dvander@780: } dvander@780: m_Title.assign(text); dvander@780: } dvander@780: dvander@780: unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item) dvander@780: { dvander@780: if (m_NextPos > 10 || !CanDrawItem(item.style)) dvander@780: { dvander@780: return 0; dvander@780: } dvander@780: dvander@780: if (item.style & ITEMDRAW_RAWLINE) dvander@780: { dvander@780: if (item.style & ITEMDRAW_SPACER) dvander@780: { dvander@785: m_BufferText.append(" \n"); dvander@780: } else { dvander@780: m_BufferText.append(item.display); dvander@780: m_BufferText.append("\n"); dvander@780: } dvander@780: return 0; dvander@780: } else if (item.style & ITEMDRAW_SPACER) { dvander@785: m_BufferText.append(" \n"); dvander@785: return m_NextPos++; dvander@785: } else if (item.style & ITEMDRAW_NOTEXT) { dvander@780: return m_NextPos++; dvander@780: } dvander@780: dvander@780: if (item.style & ITEMDRAW_DISABLED) dvander@780: { dvander@780: m_BufferText.append(g_RadioNumTable[m_NextPos]); dvander@780: m_BufferText.append(item.display); dvander@780: m_BufferText.append("\n"); dvander@780: } else { dvander@785: m_BufferText.append("->"); dvander@785: m_BufferText.append(g_RadioNumTable[m_NextPos]); dvander@780: m_BufferText.append(item.display); dvander@780: m_BufferText.append("\n"); dvander@780: keys |= (1<<(m_NextPos-1)); dvander@780: } dvander@780: dvander@780: return m_NextPos++; dvander@780: } dvander@780: dvander@780: bool CRadioDisplay::CanDrawItem(unsigned int drawFlags) dvander@780: { dvander@780: if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE) dvander@780: { dvander@780: return false; dvander@780: } dvander@780: dvander@785: if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL)) dvander@785: { dvander@785: return false; dvander@785: } dvander@785: dvander@780: return true; dvander@780: } dvander@780: dvander@780: void CRadioDisplay::SendRawDisplay(int client, unsigned int time) dvander@780: { dvander@780: char buffer[4096]; dvander@780: size_t len; dvander@780: dvander@780: len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str()); dvander@780: dvander@780: cell_t players[1] = {client}; dvander@780: dvander@819: int _sel_keys = (keys == 0) ? (1<<9) : keys; dvander@819: dvander@780: char *ptr = buffer; dvander@780: char save = 0; dvander@780: while (true) dvander@780: { dvander@780: if (len > 240) dvander@780: { dvander@780: save = ptr[240]; dvander@780: ptr[240] = '\0'; dvander@780: } dvander@780: bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0); dvander@819: buffer->WriteWord(_sel_keys); dvander@780: buffer->WriteChar(time ? time : -1); dvander@780: buffer->WriteByte( (len > 240) ? 1 : 0 ); dvander@780: buffer->WriteString(ptr); dvander@780: g_UserMsgs.EndMessage(); dvander@780: if (len > 240) dvander@780: { dvander@780: ptr[240] = save; dvander@780: ptr = &ptr[240]; dvander@780: len -= 240; dvander@780: } else { dvander@780: break; dvander@780: } dvander@780: } dvander@780: } dvander@780: dvander@780: void CRadioDisplay::DeleteThis() dvander@780: { dvander@780: delete this; dvander@780: } dvander@780: dvander@819: bool CRadioDisplay::SetSelectableKeys(unsigned int keymap) dvander@819: { dvander@819: keys = (signed)keymap; dvander@820: return true; dvander@819: } dvander@819: dvander@790: CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) : dvander@790: CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner) dvander@780: { dvander@780: } dvander@780: dvander@780: bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr) dvander@780: { dvander@780: return false; dvander@780: } dvander@780: dvander@787: IMenuPanel *CRadioMenu::CreatePanel() dvander@780: { dvander@790: return g_RadioMenuStyle.MakeRadioDisplay(this); dvander@780: } dvander@780: dvander@790: bool CRadioMenu::Display(int client, unsigned int time) dvander@780: { dvander@877: if (m_bCancelling) dvander@877: { dvander@877: return false; dvander@877: } dvander@877: dvander@790: return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time); dvander@780: } dvander@780: dvander@877: void CRadioMenu::VoteDisplay(int client, unsigned int maxTime) dvander@877: { dvander@877: if (m_bCancelling) dvander@877: { dvander@877: return; dvander@877: } dvander@877: dvander@877: g_RadioMenuStyle.DoClientMenu(client, this, m_pVoteHandler, maxTime); dvander@877: } dvander@877: dvander@780: void CRadioMenu::Cancel_Finally() dvander@780: { dvander@780: g_RadioMenuStyle.CancelMenu(this); dvander@780: } dvander@780: dvander@780: const char *g_RadioNumTable[11] = dvander@780: { dvander@785: "0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. " dvander@780: };