From 94c0783d5c246841853d4731ba8dd38654aa281d Mon Sep 17 00:00:00 2001 From: David Anderson Date: Sun, 13 May 2007 05:51:30 +0000 Subject: [PATCH] initial import of radio message - UNTESTED, DO NOT EVEN TRY LOL added supported mods for radio messages into core gameconf various internal fixes/improvements for menus --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40786 --- configs/gamedata/core.games.txt | 35 ++++ core/MenuManager.cpp | 25 +-- core/MenuManager.h | 1 + core/MenuStyle_Base.cpp | 7 +- core/MenuStyle_Base.h | 4 +- core/MenuStyle_Radio.cpp | 305 ++++++++++++++++++++++++++++++++ core/MenuStyle_Radio.h | 94 ++++++++++ core/PlayerManager.cpp | 37 ++-- core/msvc8/sourcemod_mm.vcproj | 8 + core/sourcemod.cpp | 2 + public/IMenuManager.h | 8 - 11 files changed, 481 insertions(+), 45 deletions(-) create mode 100644 core/MenuStyle_Radio.cpp create mode 100644 core/MenuStyle_Radio.h diff --git a/configs/gamedata/core.games.txt b/configs/gamedata/core.games.txt index 910da115..d558d0be 100644 --- a/configs/gamedata/core.games.txt +++ b/configs/gamedata/core.games.txt @@ -10,5 +10,40 @@ "linux" "14" } } + + } + + "cstrike" + { + "Keys" + { + "HudRadioMenuMsg" "ShowMenu" + } + } + + "dod" + { + "Keys" + { + "HudRadioMenuMsg" "ShowMenu" + } + } + + + "sourceforts" + { + "Keys" + { + "HudRadioMenuMsg" "ShowMenu" + } + } + + + "insurgency" + { + "Keys" + { + "HudRadioMenuMsg" "ShowMenu" + } } } diff --git a/core/MenuManager.cpp b/core/MenuManager.cpp index 70657d59..5c244b43 100644 --- a/core/MenuManager.cpp +++ b/core/MenuManager.cpp @@ -142,28 +142,12 @@ void VoteHandler::OnBroadcastEnd(IBaseMenu *menu) MenuManager::MenuManager() { - m_ShowMenu = -1; - m_pDefaultStyle = NULL; + m_Styles.push_back(&g_ValveMenuStyle); + SetDefaultStyle(&g_ValveMenuStyle); } void MenuManager::OnSourceModAllInitialized() { - int num = g_SMAPI->GetUserMessageCount(); - if (num >= 1) - { - for (int i=0; iGetUserMessage(i, NULL), "ShowMenu") == 0) - { - m_ShowMenu = i; - break; - } - } - } - - /* :TODO: styles */ - m_Styles.push_back(&g_ValveMenuStyle); - SetDefaultStyle(&g_ValveMenuStyle); } void MenuManager::OnSourceModAllShutdown() @@ -203,6 +187,11 @@ IMenuStyle *MenuManager::GetStyle(unsigned int index) return m_Styles[index]; } +void MenuManager::AddStyle(IMenuStyle *style) +{ + m_Styles.push_back(style); +} + unsigned int MenuManager::GetStyleCount() { return (unsigned int)m_Styles.size(); diff --git a/core/MenuManager.h b/core/MenuManager.h index ebe70320..49fd2da6 100644 --- a/core/MenuManager.h +++ b/core/MenuManager.h @@ -92,6 +92,7 @@ public: unsigned int numClients, unsigned int time); IMenuStyle *GetDefaultStyle(); + void AddStyle(IMenuStyle *style); bool SetDefaultStyle(IMenuStyle *style); IMenuDisplay *RenderMenu(int client, menu_states_t &states, ItemOrder order); protected: diff --git a/core/MenuStyle_Base.cpp b/core/MenuStyle_Base.cpp index 8731b13e..d0f582b8 100644 --- a/core/MenuStyle_Base.cpp +++ b/core/MenuStyle_Base.cpp @@ -121,13 +121,10 @@ MenuSource BaseMenuStyle::GetClientMenu(int client, void **object) } return MenuSource_Display; - } else { - return GetClientExternMenu(client, object); + } else if (player->bInExternMenu) { + return MenuSource_External; } -} -MenuSource BaseMenuStyle::GetClientExternMenu(int client, void **object) -{ return MenuSource_None; } diff --git a/core/MenuStyle_Base.h b/core/MenuStyle_Base.h index 600333ff..64c4b78a 100644 --- a/core/MenuStyle_Base.h +++ b/core/MenuStyle_Base.h @@ -43,7 +43,7 @@ public: class CBaseMenuPlayer { public: - CBaseMenuPlayer() : bInMenu(false), bAutoIgnore(false) + CBaseMenuPlayer() : bInMenu(false), bAutoIgnore(false), bInExternMenu(false) { } menu_states_t states; @@ -51,6 +51,7 @@ public: bool bAutoIgnore; float menuStartTime; unsigned int menuHoldTime; + bool bInExternMenu; }; class CBaseMenu; @@ -75,7 +76,6 @@ public: //what derived may implement virtual void AddClientToWatch(int client); virtual void RemoveClientFromWatch(int client); virtual void ProcessWatchList(); - virtual MenuSource GetClientExternMenu(int client, void **object); public: //helpers void CancelMenu(CBaseMenu *menu); void ClientPressedKey(int client, unsigned int key_press); diff --git a/core/MenuStyle_Radio.cpp b/core/MenuStyle_Radio.cpp new file mode 100644 index 00000000..1c6d485d --- /dev/null +++ b/core/MenuStyle_Radio.cpp @@ -0,0 +1,305 @@ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This file is not open source and may not be copied without explicit + * written permission of AlliedModders LLC. This file may not be redistributed + * in whole or significant part. + * For information, see LICENSE.txt or http://www.sourcemod.net/license.php + * + * Version: $Id$ + */ + +#include "MenuStyle_Radio.h" +#include "sm_stringutil.h" +#include "UserMessages.h" +#include "GameConfigs.h" + +extern const char *g_RadioNumTable[]; +CRadioStyle g_RadioMenuStyle; +int g_ShowMenuId = -1; + +CRadioStyle::CRadioStyle() : m_players(new CBaseMenuPlayer[256+1]) +{ +} + +void CRadioStyle::OnSourceModAllInitialized() +{ + const char *msg = g_pGameConf->GetKeyValue("HudRadioMenuMsg"); + if (!msg || msg[0] == '\0') + { + return; + } + + g_ShowMenuId = g_UserMsgs.GetMessageIndex(msg); + + if (!IsSupported()) + { + return; + } + + g_Menus.AddStyle(this); + g_Menus.SetDefaultStyle(this); + + g_UserMsgs.HookUserMessage(g_ShowMenuId, this, false); +} + +void CRadioStyle::OnSourceModShutdown() +{ + g_UserMsgs.UnhookUserMessage(g_ShowMenuId, this, false); +} + +bool CRadioStyle::IsSupported() +{ + return (g_ShowMenuId != -1); +} + +bool CRadioStyle::OnClientCommand(int client) +{ + const char *cmd = engine->Cmd_Argv(0); + + if (strcmp(cmd, "menuselect") == 0) + { + if (!m_players[client].bInMenu) + { + return false; + } + int arg = atoi(engine->Cmd_Argv(1)); + ClientPressedKey(client, arg); + } + + return false; +} + +static unsigned int g_last_holdtime = 0; +static unsigned int g_last_client_count = 0; +static int g_last_clients[256]; + +void CRadioStyle::OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter) +{ + int count = pFilter->GetRecipientCount(); + bf_read br(bf->GetBasePointer(), 2); + + br.ReadWord(); + int c = br.ReadChar(); + + g_last_holdtime = (c == -1) ? 0 : (unsigned)c; + + for (int i=0; iGetRecipientIndex(i); + } +} + +void CRadioStyle::OnUserMessageSent(int msg_id) +{ + for (unsigned int i=0; iSendRawDisplay(client, m_players[client].menuHoldTime); +} + +IMenuDisplay *CRadioStyle::CreateDisplay() +{ + return new CRadioDisplay(); +} + +IBaseMenu *CRadioStyle::CreateMenu() +{ + return new CRadioMenu(); +} + +unsigned int CRadioStyle::GetMaxPageItems() +{ + return 10; +} + +const char *CRadioStyle::GetStyleName() +{ + return "radio"; +} + +CBaseMenuPlayer *CRadioStyle::GetMenuPlayer(int client) +{ + return &m_players[client]; +} + +CRadioDisplay::CRadioDisplay() +{ + Reset(); +} + +CRadioDisplay::CRadioDisplay(CRadioMenu *menu) +{ + Reset(); +} + +bool CRadioDisplay::DrawRawLine(const char *rawline) +{ + m_BufferText.append(rawline); + m_BufferText.append("\n"); + return true; +} + +void CRadioDisplay::Reset() +{ + m_BufferText.assign(""); + m_Title.assign(""); + m_NextPos = 1; +} + +bool CRadioDisplay::SendDisplay(int client, IMenuHandler *handler, unsigned int time) +{ + return g_RadioMenuStyle.DoClientMenu(client, this, handler, time); +} + +bool CRadioDisplay::SetExtOption(MenuOption option, const void *valuePtr) +{ + return false; +} + +IMenuStyle *CRadioDisplay::GetParentStyle() +{ + return &g_RadioMenuStyle; +} + +void CRadioDisplay::DrawTitle(const char *text, bool onlyIfEmpty/* =false */) +{ + if (m_Title.size() != 0 && onlyIfEmpty) + { + return; + } + m_Title.assign(text); +} + +unsigned int CRadioDisplay::DrawItem(const ItemDrawInfo &item) +{ + if (m_NextPos > 10 || !CanDrawItem(item.style)) + { + return 0; + } + + if (item.style & ITEMDRAW_RAWLINE) + { + if (item.style & ITEMDRAW_SPACER) + { + m_BufferText.append("\n"); + } else { + m_BufferText.append(item.display); + m_BufferText.append("\n"); + } + return 0; + } else if (item.style & ITEMDRAW_SPACER) { + m_BufferText.append("\n"); + return m_NextPos++; + } + + if (item.style & ITEMDRAW_DISABLED) + { + m_BufferText.append(g_RadioNumTable[m_NextPos]); + m_BufferText.append(". "); + m_BufferText.append(item.display); + m_BufferText.append("\n"); + } else { + m_BufferText.append("->. "); + m_BufferText.append(item.display); + m_BufferText.append("\n"); + keys |= (1<<(m_NextPos-1)); + } + + return m_NextPos++; +} + +bool CRadioDisplay::CanDrawItem(unsigned int drawFlags) +{ + if ((drawFlags & ITEMDRAW_IGNORE) == ITEMDRAW_IGNORE) + { + return false; + } + + return true; +} + +void CRadioDisplay::SendRawDisplay(int client, unsigned int time) +{ + char buffer[4096]; + size_t len; + + len = UTIL_Format(buffer, sizeof(buffer), "%s\n%s", m_Title.c_str(), m_BufferText.c_str()); + + cell_t players[1] = {client}; + + char *ptr = buffer; + char save = 0; + while (true) + { + if (len > 240) + { + save = ptr[240]; + ptr[240] = '\0'; + } + bf_write *buffer = g_UserMsgs.StartMessage(g_ShowMenuId, players, 1, 0); + buffer->WriteWord(keys); + buffer->WriteChar(time ? time : -1); + buffer->WriteByte( (len > 240) ? 1 : 0 ); + buffer->WriteString(ptr); + g_UserMsgs.EndMessage(); + if (len > 240) + { + ptr[240] = save; + ptr = &ptr[240]; + len -= 240; + } else { + break; + } + } +} + +void CRadioDisplay::DeleteThis() +{ + delete this; +} + +CRadioMenu::CRadioMenu() : CBaseMenu(&g_RadioMenuStyle) +{ +} + +bool CRadioMenu::SetExtOption(MenuOption option, const void *valuePtr) +{ + return false; +} + +IMenuDisplay *CRadioMenu::CreateDisplay() +{ + return new CRadioDisplay(this); +} + +bool CRadioMenu::Display(int client, IMenuHandler *handler, unsigned int time) +{ + return g_RadioMenuStyle.DoClientMenu(client, this, handler, time); +} + +void CRadioMenu::Cancel_Finally() +{ + g_RadioMenuStyle.CancelMenu(this); +} + +const char *g_RadioNumTable[11] = +{ + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0" +}; diff --git a/core/MenuStyle_Radio.h b/core/MenuStyle_Radio.h new file mode 100644 index 00000000..dd25e1ea --- /dev/null +++ b/core/MenuStyle_Radio.h @@ -0,0 +1,94 @@ +/** + * vim: set ts=4 : + * =============================================================== + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * =============================================================== + * + * This file is not open source and may not be copied without explicit + * written permission of AlliedModders LLC. This file may not be redistributed + * in whole or significant part. + * For information, see LICENSE.txt or http://www.sourcemod.net/license.php + * + * Version: $Id$ + */ + +#ifndef _INCLUDE_MENUSTYLE_RADIO_H +#define _INCLUDE_MENUSTYLE_RADIO_H + +#include "sm_globals.h" +#include "MenuManager.h" +#include "MenuStyle_Base.h" +#include "sourcemm_api.h" +#include +#include +#include "sm_fastlink.h" + +using namespace SourceMod; + +class CRadioStyle : + public BaseMenuStyle, + public SMGlobalClass, + public IUserMessageListener +{ +public: + CRadioStyle(); +public: //SMGlobalClass + void OnSourceModAllInitialized(); + void OnSourceModShutdown(); +public: //BaseMenuStyle + CBaseMenuPlayer *GetMenuPlayer(int client); + void SendDisplay(int client, IMenuDisplay *display); +public: //IMenuStyle + const char *GetStyleName(); + IMenuDisplay *CreateDisplay(); + IBaseMenu *CreateMenu(); + unsigned int GetMaxPageItems(); +public: //IUserMessageListener + void OnUserMessage(int msg_id, bf_write *bf, IRecipientFilter *pFilter); + void OnUserMessageSent(int msg_id); +public: + bool IsSupported(); + bool OnClientCommand(int client); +private: + CBaseMenuPlayer *m_players; +}; + +class CRadioMenu; + +class CRadioDisplay : public IMenuDisplay +{ +public: + CRadioDisplay(); + CRadioDisplay(CRadioMenu *menu); +public: //IMenuDisplay + IMenuStyle *GetParentStyle(); + void Reset(); + void DrawTitle(const char *text, bool onlyIfEmpty=false); + unsigned int DrawItem(const ItemDrawInfo &item); + bool DrawRawLine(const char *rawline); + bool SetExtOption(MenuOption option, const void *valuePtr); + bool CanDrawItem(unsigned int drawFlags); + bool SendDisplay(int client, IMenuHandler *handler, unsigned int time); + void DeleteThis(); + void SendRawDisplay(int client, unsigned int time); +private: + String m_BufferText; + String m_Title; + unsigned int m_NextPos; + int keys; +}; + +class CRadioMenu : public CBaseMenu +{ +public: + CRadioMenu(); +public: + bool SetExtOption(MenuOption option, const void *valuePtr); + IMenuDisplay *CreateDisplay(); + bool Display(int client, IMenuHandler *handler, unsigned int time); + void Cancel_Finally(); +}; + +extern CRadioStyle g_RadioMenuStyle; + +#endif //_INCLUDE_MENUSTYLE_RADIO_H diff --git a/core/PlayerManager.cpp b/core/PlayerManager.cpp index 6260285e..15708383 100644 --- a/core/PlayerManager.cpp +++ b/core/PlayerManager.cpp @@ -18,6 +18,7 @@ #include "AdminCache.h" #include "ConCmdManager.h" #include "MenuStyle_Valve.h" +#include "MenuStyle_Radio.h" PlayerManager g_Players; @@ -385,24 +386,36 @@ void PlayerManager::OnClientDisconnect_Post(edict_t *pEntity) void PlayerManager::OnClientCommand(edict_t *pEntity) { - cell_t res = Pl_Continue; int client = engine->IndexOfEdict(pEntity); - - int args = engine->Cmd_Argc() - 1; - - m_clcommand->PushCell(client); - m_clcommand->PushCell(args); - m_clcommand->Execute(&res, NULL); - - if (res >= Pl_Stop) - { - RETURN_META(MRES_SUPERCEDE); - } + cell_t res = Pl_Continue; bool result = g_ValveMenuStyle.OnClientCommand(client); if (result) { res = Pl_Handled; + } else { + result = g_RadioMenuStyle.OnClientCommand(client); + if (result) + { + res = Pl_Handled; + } + } + + int args = engine->Cmd_Argc() - 1; + + cell_t res2 = Pl_Continue; + m_clcommand->PushCell(client); + m_clcommand->PushCell(args); + m_clcommand->Execute(&res2, NULL); + + if (res2 > res) + { + res = res2; + } + + if (res >= Pl_Stop) + { + RETURN_META(MRES_SUPERCEDE); } res = g_ConCmds.DispatchClientCommand(client, (ResultType)res); diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index 09667d5a..bcd11703 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -235,6 +235,10 @@ RelativePath="..\MenuStyle_Base.cpp" > + + @@ -353,6 +357,10 @@ RelativePath="..\MenuStyle_Base.h" > + + diff --git a/core/sourcemod.cpp b/core/sourcemod.cpp index 95eaaf8a..42b7e691 100644 --- a/core/sourcemod.cpp +++ b/core/sourcemod.cpp @@ -30,6 +30,7 @@ #include "ForwardSys.h" #include "TimerSys.h" #include "MenuStyle_Valve.h" +#include "MenuStyle_Radio.h" SH_DECL_HOOK6(IServerGameDLL, LevelInit, SH_NOATTRIB, false, bool, const char *, const char *, const char *, const char *, bool, bool); SH_DECL_HOOK0_void(IServerGameDLL, LevelShutdown, SH_NOATTRIB, false); @@ -390,6 +391,7 @@ void SourceModBase::GameFrame(bool simulating) if (g_SimTicks.tickcount && (curtime - g_LastMenuTime >= 1.0f)) { g_ValveMenuStyle.ProcessWatchList(); + g_RadioMenuStyle.ProcessWatchList(); g_LastMenuTime = curtime; } diff --git a/public/IMenuManager.h b/public/IMenuManager.h index 60c4742c..b48479a8 100644 --- a/public/IMenuManager.h +++ b/public/IMenuManager.h @@ -617,14 +617,6 @@ namespace SourceMod */ virtual IMenuStyle *GetDefaultStyle() =0; - /** - * @brief Sets the default draw style Core uses. - * - * @param style Menu style. - * @return True on success, false on failure. - */ - virtual bool SetDefaultStyle(IMenuStyle *style) =0; - /** * @brief Given a set of menu states, converts it to an IDisplay object. *