3 * ===============================================================
4 * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved.
5 * ===============================================================
7 * This file is not open source and may not be copied without explicit
8 * written permission of AlliedModders LLC. This file may not be redistributed
9 * in whole or significant part.
10 * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
15 #include "MenuStyle_Radio.h"
16 #include "sm_stringutil.h"
17 #include "UserMessages.h"
18 #include "GameConfigs.h"
19 #include "PlayerManager.h"
20 #if defined MENU_DEBUG
24 extern const char *g_RadioNumTable[];
25 CRadioStyle g_RadioMenuStyle;
26 int g_ShowMenuId = -1;
27 bool g_bRadioInit = false;
29 CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
33 void CRadioStyle::OnSourceModAllInitialized()
35 g_Players.AddClientListener(this);
38 void CRadioStyle::OnSourceModLevelChange(const char *mapName)
46 const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
47 if (!msg || msg[0] == '\0')
52 g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
59 g_Menus.AddStyle(this);
60 g_Menus.SetDefaultStyle(this);
62 g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
65 void CRadioStyle::OnSourceModShutdown()
67 g_Players.RemoveClientListener(this);
68 g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
70 while (!m_FreeDisplays.empty())
72 delete m_FreeDisplays.front();
77 bool CRadioStyle::IsSupported()
79 return (g_ShowMenuId != -1);
82 bool CRadioStyle::OnClientCommand(int client)
84 const char *cmd = engine->Cmd_Argv(0);
86 if (strcmp(cmd, "menuselect") == 0)
88 if (!m_players[client].bInMenu)
93 int arg = atoi(engine->Cmd_Argv(1));
94 ClientPressedKey(client, arg);
101 static unsigned int g_last_holdtime = 0;
102 static unsigned int g_last_client_count = 0;
103 static int g_last_clients[256];
105 void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
107 int count = pFilter->GetRecipientCount();
108 bf_read br(bf->GetBasePointer(), 2);
111 int c = br.ReadChar();
113 g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
115 for (int i=0; i<count; i++)
117 g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
121 void CRadioStyle::OnUserMessageSent(int msg_id)
123 for (unsigned int i=0; i<g_last_client_count; i++)
125 int client = g_last_clients[i];
126 #if defined MENU_DEBUG
127 g_Logger.LogMessage("[SM_MENU] CRadioStyle got ShowMenu (client %d) (bInMenu %d)",
129 m_players[client].bInExternMenu);
131 if (m_players[client].bInMenu)
133 _CancelClientMenu(client, true);
135 m_players[client].bInExternMenu = true;
136 m_players[client].menuHoldTime = g_last_holdtime;
138 g_last_client_count = 0;
141 void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
143 CRadioDisplay *rDisplay = (CRadioDisplay *)display;
144 rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
147 IMenuPanel *CRadioStyle::CreatePanel()
149 return g_RadioMenuStyle.MakeRadioDisplay();
152 IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
154 return new CRadioMenu(pHandler, pOwner);
157 unsigned int CRadioStyle::GetMaxPageItems()
162 const char *CRadioStyle::GetStyleName()
167 CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
169 return &m_players[client];
172 CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
174 CRadioDisplay *display;
175 if (m_FreeDisplays.empty())
177 display = new CRadioDisplay();
179 display = m_FreeDisplays.front();
180 m_FreeDisplays.pop();
186 void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
188 m_FreeDisplays.push(display);
191 CRadioDisplay::CRadioDisplay()
196 CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
201 bool CRadioDisplay::DrawRawLine(const char *rawline)
203 m_BufferText.append(rawline);
204 m_BufferText.append("\n");
208 void CRadioDisplay::Reset()
210 m_BufferText.assign("");
216 unsigned int CRadioDisplay::GetCurrentKey()
221 bool CRadioDisplay::SetCurrentKey(unsigned int key)
223 if (key < m_NextPos || m_NextPos > 10)
233 bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
235 return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
238 bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
243 IMenuStyle *CRadioDisplay::GetParentStyle()
245 return &g_RadioMenuStyle;
248 void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
250 if (m_Title.size() != 0 && onlyIfEmpty)
254 m_Title.assign(text);
257 unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
259 if (m_NextPos > 10 || !CanDrawItem(item.style))
264 if (item.style & ITEMDRAW_RAWLINE)
266 if (item.style & ITEMDRAW_SPACER)
268 m_BufferText.append(" \n");
270 m_BufferText.append(item.display);
271 m_BufferText.append("\n");
274 } else if (item.style & ITEMDRAW_SPACER) {
275 m_BufferText.append(" \n");
277 } else if (item.style & ITEMDRAW_NOTEXT) {
281 if (item.style & ITEMDRAW_DISABLED)
283 m_BufferText.append(g_RadioNumTable[m_NextPos]);
284 m_BufferText.append(item.display);
285 m_BufferText.append("\n");
287 m_BufferText.append("->");
288 m_BufferText.append(g_RadioNumTable[m_NextPos]);
289 m_BufferText.append(item.display);
290 m_BufferText.append("\n");
291 keys |= (1<<(m_NextPos-1));
297 bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
299 if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
304 if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
312 void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
317 len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
319 cell_t players[1] = {client};
321 int _sel_keys = (keys == 0) ? (1<<9) : keys;
332 bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0);
333 buffer->WriteWord(_sel_keys);
334 buffer->WriteChar(time ? time : -1);
335 buffer->WriteByte( (len > 240) ? 1 : 0 );
336 buffer->WriteString(ptr);
337 g_UserMsgs.EndMessage();
349 void CRadioDisplay::DeleteThis()
354 bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
356 keys = (signed)keymap;
360 CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
361 CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
365 bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
370 IMenuPanel *CRadioMenu::CreatePanel()
372 return g_RadioMenuStyle.MakeRadioDisplay(this);
375 bool CRadioMenu::Display(int client, unsigned int time)
377 #if defined MENU_DEBUG
378 g_Logger.LogMessage("[SM_MENU] CRadioMenu::Display(%p) (client %d) (time %d)",
388 return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time);
391 void CRadioMenu::VoteDisplay(int client, unsigned int maxTime)
393 #if defined MENU_DEBUG
394 g_Logger.LogMessage("[SM_MENU] CRadioMenu::VoteDisplay(%p) (client %d) (time %d)",
404 g_RadioMenuStyle.DoClientMenu(client, this, m_pVoteHandler, maxTime);
407 void CRadioMenu::Cancel_Finally()
409 g_RadioMenuStyle.CancelMenu(this);
412 const char *g_RadioNumTable[11] =
414 "0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "