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"
20 extern const char *g_RadioNumTable[];
21 CRadioStyle g_RadioMenuStyle;
22 int g_ShowMenuId = -1;
23 bool g_bRadioInit = false;
25 CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
29 void CRadioStyle::OnSourceModLevelChange(const char *mapName)
37 const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
38 if (!msg || msg[0] == '\0')
43 g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
50 g_Menus.AddStyle(this);
51 g_Menus.SetDefaultStyle(this);
53 g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
56 void CRadioStyle::OnSourceModShutdown()
58 g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
60 while (!m_FreeDisplays.empty())
62 delete m_FreeDisplays.front();
67 bool CRadioStyle::IsSupported()
69 return (g_ShowMenuId != -1);
72 bool CRadioStyle::OnClientCommand(int client)
74 const char *cmd = engine->Cmd_Argv(0);
76 if (strcmp(cmd, "menuselect") == 0)
78 if (!m_players[client].bInMenu)
83 int arg = atoi(engine->Cmd_Argv(1));
84 ClientPressedKey(client, arg);
91 static unsigned int g_last_holdtime = 0;
92 static unsigned int g_last_client_count = 0;
93 static int g_last_clients[256];
95 void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
97 int count = pFilter->GetRecipientCount();
98 bf_read br(bf->GetBasePointer(), 2);
101 int c = br.ReadChar();
103 g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
105 for (int i=0; i<count; i++)
107 g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
111 void CRadioStyle::OnUserMessageSent(int msg_id)
113 for (unsigned int i=0; i<g_last_client_count; i++)
115 int client = g_last_clients[i];
116 if (m_players[client].bInMenu)
118 _CancelClientMenu(client, true);
120 m_players[client].bInExternMenu = true;
121 m_players[client].menuHoldTime = g_last_holdtime;
123 g_last_client_count = 0;
126 void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
128 CRadioDisplay *rDisplay = (CRadioDisplay *)display;
129 rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
132 IMenuPanel *CRadioStyle::CreatePanel()
134 return g_RadioMenuStyle.MakeRadioDisplay();
137 IBaseMenu *CRadioStyle::CreateMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner)
139 return new CRadioMenu(pHandler, pOwner);
142 unsigned int CRadioStyle::GetMaxPageItems()
147 const char *CRadioStyle::GetStyleName()
152 CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
154 return &m_players[client];
157 CRadioDisplay *CRadioStyle::MakeRadioDisplay(CRadioMenu *menu)
159 CRadioDisplay *display;
160 if (m_FreeDisplays.empty())
162 display = new CRadioDisplay();
164 display = m_FreeDisplays.front();
165 m_FreeDisplays.pop();
171 void CRadioStyle::FreeRadioDisplay(CRadioDisplay *display)
173 m_FreeDisplays.push(display);
176 CRadioDisplay::CRadioDisplay()
181 CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
186 bool CRadioDisplay::DrawRawLine(const char *rawline)
188 m_BufferText.append(rawline);
189 m_BufferText.append("\n");
193 void CRadioDisplay::Reset()
195 m_BufferText.assign("");
201 bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
203 return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
206 bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
211 IMenuStyle *CRadioDisplay::GetParentStyle()
213 return &g_RadioMenuStyle;
216 void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
218 if (m_Title.size() != 0 && onlyIfEmpty)
222 m_Title.assign(text);
225 unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
227 if (m_NextPos > 10 || !CanDrawItem(item.style))
232 if (item.style & ITEMDRAW_RAWLINE)
234 if (item.style & ITEMDRAW_SPACER)
236 m_BufferText.append(" \n");
238 m_BufferText.append(item.display);
239 m_BufferText.append("\n");
242 } else if (item.style & ITEMDRAW_SPACER) {
243 m_BufferText.append(" \n");
245 } else if (item.style & ITEMDRAW_NOTEXT) {
249 if (item.style & ITEMDRAW_DISABLED)
251 m_BufferText.append(g_RadioNumTable[m_NextPos]);
252 m_BufferText.append(item.display);
253 m_BufferText.append("\n");
255 m_BufferText.append("->");
256 m_BufferText.append(g_RadioNumTable[m_NextPos]);
257 m_BufferText.append(item.display);
258 m_BufferText.append("\n");
259 keys |= (1<<(m_NextPos-1));
265 bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
267 if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
272 if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
280 void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
285 len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
287 cell_t players[1] = {client};
289 int _sel_keys = (keys == 0) ? (1<<9) : keys;
300 bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0);
301 buffer->WriteWord(_sel_keys);
302 buffer->WriteChar(time ? time : -1);
303 buffer->WriteByte( (len > 240) ? 1 : 0 );
304 buffer->WriteString(ptr);
305 g_UserMsgs.EndMessage();
317 void CRadioDisplay::DeleteThis()
322 bool CRadioDisplay::SetSelectableKeys(unsigned int keymap)
324 keys = (signed)keymap;
327 CRadioMenu::CRadioMenu(IMenuHandler *pHandler, IdentityToken_t *pOwner) :
328 CBaseMenu(pHandler, &g_RadioMenuStyle, pOwner)
332 bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
337 IMenuPanel *CRadioMenu::CreatePanel()
339 return g_RadioMenuStyle.MakeRadioDisplay(this);
342 bool CRadioMenu::Display(int client, unsigned int time)
344 return g_RadioMenuStyle.DoClientMenu(client, this, m_pHandler, time);
347 void CRadioMenu::Cancel_Finally()
349 g_RadioMenuStyle.CancelMenu(this);
352 const char *g_RadioNumTable[11] =
354 "0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "