core/MenuStyle_Radio.cpp
author David Anderson <dvander@alliedmods.net>
Sun May 13 18:55:59 2007 +0000 (2007-05-13)
changeset 787 52283fe61d42
parent 785 bca431afd754
child 790 9b1474d03470
permissions -rw-r--r--
changed IMenuDisplay/CreateDisplay to IMenuPanel/CreatePanel
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     5  * ===============================================================
     6  *
     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
    11  *
    12  * Version: $Id$
    13  */
    14 
    15 #include "MenuStyle_Radio.h"
    16 #include "sm_stringutil.h"
    17 #include "UserMessages.h"
    18 #include "GameConfigs.h"
    19 
    20 extern const char *g_RadioNumTable[];
    21 CRadioStyle g_RadioMenuStyle;
    22 int g_ShowMenuId = -1;
    23 bool g_bRadioInit = false;
    24 
    25 CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1])
    26 {
    27 }
    28 
    29 void CRadioStyle::OnSourceModLevelChange(const char *mapName)
    30 {
    31 	if (g_bRadioInit)
    32 	{
    33 		return;
    34 	}
    35 
    36 	g_bRadioInit = true;
    37 	const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg");
    38 	if (!msg || msg[0] == '\0')
    39 	{
    40 		return;
    41 	}
    42 
    43 	g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg);
    44 
    45 	if (!IsSupported())
    46 	{
    47 		return;
    48 	}
    49 
    50 	g_Menus.AddStyle(this);
    51 	g_Menus.SetDefaultStyle(this);
    52 
    53 	g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false);
    54 }
    55 
    56 void CRadioStyle::OnSourceModShutdown()
    57 {
    58 	g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false);
    59 }
    60 
    61 bool CRadioStyle::IsSupported()
    62 {
    63 	return (g_ShowMenuId != -1);
    64 }
    65 
    66 bool CRadioStyle::OnClientCommand(int client)
    67 {
    68 	const char *cmd = engine->Cmd_Argv(0);
    69 
    70 	if (strcmp(cmd, "menuselect") == 0)
    71 	{
    72 		if (!m_players[client].bInMenu)
    73 		{
    74 			return false;
    75 		}
    76 
    77 		int arg = atoi(engine->Cmd_Argv(1));
    78 		ClientPressedKey(client, arg);
    79 		return true;
    80 	}
    81 
    82 	return false;
    83 }
    84 
    85 static unsigned int g_last_holdtime = 0;
    86 static unsigned int g_last_client_count = 0;
    87 static int g_last_clients[256];
    88 
    89 void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter)
    90 {
    91 	int count = pFilter->GetRecipientCount();
    92 	bf_read br(bf->GetBasePointer(), 2);
    93 
    94 	br.ReadWord();
    95 	int c = br.ReadChar();
    96 
    97 	g_last_holdtime = (c == -1) ? 0 : (unsigned)c;
    98 
    99 	for (int i=0; i<count; i++)
   100 	{
   101 		g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
   102 	}
   103 }
   104 
   105 void CRadioStyle::OnUserMessageSent(int msg_id)
   106 {
   107 	for (unsigned int i=0; i<g_last_client_count; i++)
   108 	{
   109 		int client = g_last_clients[i];
   110 		if (m_players[client].bInMenu)
   111 		{
   112 			_CancelClientMenu(client, true);
   113 		}
   114 		m_players[client].bInExternMenu = true;
   115 		m_players[client].menuHoldTime = g_last_holdtime;
   116 	}
   117 	g_last_client_count = 0;
   118 }
   119 
   120 void CRadioStyle::SendDisplay(int client, IMenuPanel *display)
   121 {
   122 	CRadioDisplay *rDisplay = (CRadioDisplay *)display;
   123 	rDisplay->SendRawDisplay(client, m_players[client].menuHoldTime);
   124 }
   125 
   126 IMenuPanel *CRadioStyle::CreatePanel()
   127 {
   128 	return new CRadioDisplay();
   129 }
   130 
   131 IBaseMenu *CRadioStyle::CreateMenu()
   132 {
   133 	return new CRadioMenu();
   134 }
   135 
   136 unsigned int CRadioStyle::GetMaxPageItems()
   137 {
   138 	return 10;
   139 }
   140 
   141 const char *CRadioStyle::GetStyleName()
   142 {
   143 	return "radio";
   144 }
   145 
   146 CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client)
   147 {
   148 	return &m_players[client];
   149 }
   150 
   151 CRadioDisplay::CRadioDisplay()
   152 {
   153 	Reset();
   154 }
   155 
   156 CRadioDisplay::CRadioDisplay(CRadioMenu *menu)
   157 {
   158 	Reset();
   159 }
   160 
   161 bool CRadioDisplay::DrawRawLine(const char *rawline)
   162 {
   163 	m_BufferText.append(rawline);
   164 	m_BufferText.append("\n");
   165 	return true;
   166 }
   167 
   168 void CRadioDisplay::Reset()
   169 {
   170 	m_BufferText.assign("");
   171 	m_Title.assign("");
   172 	m_NextPos = 1;
   173 	keys = 0;
   174 }
   175 
   176 bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time)
   177 {
   178 	return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
   179 }
   180 
   181 bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr)
   182 {
   183 	return false;
   184 }
   185 
   186 IMenuStyle *CRadioDisplay::GetParentStyle()
   187 {
   188 	return &g_RadioMenuStyle;
   189 }
   190 
   191 void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */)
   192 {
   193 	if (m_Title.size() != 0 && onlyIfEmpty)
   194 	{
   195 		return;
   196 	}
   197 	m_Title.assign(text);
   198 }
   199 
   200 unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item)
   201 {
   202 	if (m_NextPos > 10 || !CanDrawItem(item.style))
   203 	{
   204 		return 0;
   205 	}
   206 
   207 	if (item.style & ITEMDRAW_RAWLINE)
   208 	{
   209 		if (item.style & ITEMDRAW_SPACER)
   210 		{
   211 			m_BufferText.append(" \n");
   212 		} else {
   213 			m_BufferText.append(item.display);
   214 			m_BufferText.append("\n");
   215 		}
   216 		return 0;
   217 	} else if (item.style & ITEMDRAW_SPACER) {
   218 		m_BufferText.append(" \n");
   219 		return m_NextPos++;
   220 	} else if (item.style & ITEMDRAW_NOTEXT) {
   221 		return m_NextPos++;
   222 	}
   223 
   224 	if (item.style & ITEMDRAW_DISABLED)
   225 	{
   226 		m_BufferText.append(g_RadioNumTable[m_NextPos]);
   227 		m_BufferText.append(item.display);
   228 		m_BufferText.append("\n");
   229 	} else {
   230 		m_BufferText.append("->");
   231 		m_BufferText.append(g_RadioNumTable[m_NextPos]);
   232 		m_BufferText.append(item.display);
   233 		m_BufferText.append("\n");
   234 		keys |= (1<<(m_NextPos-1));
   235 	}
   236 
   237 	return m_NextPos++;
   238 }
   239 
   240 bool CRadioDisplay::CanDrawItem(unsigned int drawFlags)
   241 {
   242 	if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE)
   243 	{
   244 		return false;
   245 	}
   246 
   247 	if ((drawFlags & ITEMDRAW_DISABLED) && (drawFlags & ITEMDRAW_CONTROL))
   248 	{
   249 		return false;
   250 	}
   251 
   252 	return true;
   253 }
   254 
   255 void CRadioDisplay::SendRawDisplay(int client, unsigned int time)
   256 {
   257 	char buffer[4096];
   258 	size_t len;
   259 
   260 	len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str());
   261 
   262 	cell_t players[1] = {client};
   263 
   264 	char *ptr = buffer;
   265 	char save = 0;
   266 	while (true)
   267 	{
   268 		if (len > 240)
   269 		{
   270 			save = ptr[240];
   271 			ptr[240] = '\0';
   272 		}
   273 		bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0);
   274 		buffer->WriteWord(keys);
   275 		buffer->WriteChar(time ? time : -1);
   276 		buffer->WriteByte( (len > 240) ? 1 : 0 );
   277 		buffer->WriteString(ptr);
   278 		g_UserMsgs.EndMessage();
   279 		if (len > 240)
   280 		{
   281 			ptr[240] = save;
   282 			ptr = &ptr[240];
   283 			len -= 240;
   284 		} else {
   285 			break;
   286 		}
   287 	}
   288 }
   289 
   290 void CRadioDisplay::DeleteThis()
   291 {
   292 	delete this;
   293 }
   294 
   295 CRadioMenu::CRadioMenu() : CBaseMenu(&g_RadioMenuStyle)
   296 {
   297 }
   298 
   299 bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr)
   300 {
   301 	return false;
   302 }
   303 
   304 IMenuPanel *CRadioMenu::CreatePanel()
   305 {
   306 	return new CRadioDisplay(this);
   307 }
   308 
   309 bool CRadioMenu::Display(int client, IMenuHandler *handler, unsigned int time)
   310 {
   311 	return g_RadioMenuStyle.DoClientMenu(client, this, handler, time);
   312 }
   313 
   314 void CRadioMenu::Cancel_Finally()
   315 {
   316 	g_RadioMenuStyle.CancelMenu(this);
   317 }
   318 
   319 const char *g_RadioNumTable[11] = 
   320 {
   321 	"0. ", "1. ", "2. ", "3. ", "4. ", "5. ", "6. ", "7. ", "8. ", "9. ", "0. "
   322 };