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"
21 extern const char *g_RadioNumTable[];
22 CRadioStyle g_RadioMenuStyle;
23 int g_ShowMenuId = -1;
24 bool g_bRadioInit = false;
26 CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
30 void CRadioStyle::OnSourceModAllInitialized()
32 g_Players.AddClientListener(this);
35 void CRadioStyle::OnSourceModLevelChange(const char *mapName)
43 const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
44 if (!msg || msg[0] == '\0')
49 g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
56 g_Menus.AddStyle(this);
57 g_Menus.SetDefaultStyle(this);
59 g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
62 void CRadioStyle::OnSourceModShutdown()
64 g_Players.RemoveClientListener(this);
65 g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
67 while (!m_FreeDisplays.empty())
69 delete m_FreeDisplays.front();
74 bool CRadioStyle::IsSupported()
76 return (g_ShowMenuId != -1);
79 bool CRadioStyle::OnClientCommand(int client)
81 const char *cmd = engine->Cmd_Argv(0);
83 if (strcmp(cmd, "menuselect") == 0)
85 if (!m_players[client].bInMenu)
90 int arg = atoi(engine->Cmd_Argv(1));
91 ClientPressedKey(client, arg);
98 static unsigned int g_last_holdtime = 0;
99 static unsigned int g_last_client_count = 0;
100 static int g_last_clients[256];
102 void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
104 int count = pFilter->GetRecipientCount();
105 bf_read br(bf->GetBasePointer(), 2);
108 int c = br.ReadChar();
110 g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
112 for (int i=0; i<count; i++)
114 g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
118 void CRadioStyle::OnUserMessageSent(int msg_id)
120 for (unsigned int i=0; i<g_last_client_count; i++)
122 int client = g_last_clients[i];
123 if (m_players[client].bInMenu)
125 _CancelClientMenu(client, true);
127 m_players[client].bInExternMenu = true;
128 m_players[client].menuHoldTime = g_last_holdtime;
130 g_last_client_count = 0;
133 void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
135 CRadioDisplay *rDisplay = (CRadioDisplay *)display;
136 rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
139 IMenuPanel *CRadioStyle::CreatePanel()
141 return g_RadioMenuStyle.MakeRadioDisplay();
144 IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
146 return new CRadioMenu(pHandler, pOwner);
149 unsigned int CRadioStyle::GetMaxPageItems()
154 const char *CRadioStyle::GetStyleName()
159 CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
161 return &m_players[client];
164 CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
166 CRadioDisplay *display;
167 if (m_FreeDisplays.empty())
169 display = new CRadioDisplay();
171 display = m_FreeDisplays.front();
172 m_FreeDisplays.pop();
178 void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
180 m_FreeDisplays.push(display);
183 CRadioDisplay::CRadioDisplay()
188 CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
193 bool CRadioDisplay::DrawRawLine(const char *rawline)
195 m_BufferText.append(rawline);
196 m_BufferText.append("\n");
200 void CRadioDisplay::Reset()
202 m_BufferText.assign("");
208 unsigned int CRadioDisplay::GetCurrentKey()
213 bool CRadioDisplay::SetCurrentKey(unsigned int key)
215 if (key < m_NextPos || m_NextPos > 10)
225 bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
227 return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
230 bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
235 IMenuStyle *CRadioDisplay::GetParentStyle()
237 return &g_RadioMenuStyle;
240 void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
242 if (m_Title.size() != 0 && onlyIfEmpty)
246 m_Title.assign(text);
249 unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
251 if (m_NextPos > 10 || !CanDrawItem(item.style))
256 if (item.style & ITEMDRAW_RAWLINE)
258 if (item.style & ITEMDRAW_SPACER)
260 m_BufferText.append(" \n");
262 m_BufferText.append(item.display);
263 m_BufferText.append("\n");
266 } else if (item.style & ITEMDRAW_SPACER) {
267 m_BufferText.append(" \n");
269 } else if (item.style & ITEMDRAW_NOTEXT) {
273 if (item.style & ITEMDRAW_DISABLED)
275 m_BufferText.append(g_RadioNumTable[m_NextPos]);
276 m_BufferText.append(item.display);
277 m_BufferText.append("\n");
279 m_BufferText.append("->");
280 m_BufferText.append(g_RadioNumTable[m_NextPos]);
281 m_BufferText.append(item.display);
282 m_BufferText.append("\n");
283 keys |= (1<<(m_NextPos-1));
289 bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
291 if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
296 if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
304 void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
309 len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
311 cell_t players[1] = {client};
313 int _sel_keys = (keys == 0) ? (1<<9) : keys;
324 bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0);
325 buffer->WriteWord(_sel_keys);
326 buffer->WriteChar(time ? time : -1);
327 buffer->WriteByte( (len > 240) ? 1 : 0 );
328 buffer->WriteString(ptr);
329 g_UserMsgs.EndMessage();
341 void CRadioDisplay::DeleteThis()
346 bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
348 keys = (signed)keymap;
352 CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
353 CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
357 bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
362 IMenuPanel *CRadioMenu::CreatePanel()
364 return g_RadioMenuStyle.MakeRadioDisplay(this);
367 bool CRadioMenu::Display(int client, unsigned int time)
369 return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time);
372 void CRadioMenu::Cancel_Finally()
374 g_RadioMenuStyle.CancelMenu(this);
377 const char *g_RadioNumTable[11] =
379 "0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "