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
This commit is contained in:
David Anderson 2007-05-13 05:51:30 +00:00
parent 11bd835e55
commit 94c0783d5c
11 changed files with 481 additions and 45 deletions

View File

@ -10,5 +10,40 @@
"linux" "14"
}
}
}
"cstrike"
{
"Keys"
{
"HudRadioMenuMsg" "ShowMenu"
}
}
"dod"
{
"Keys"
{
"HudRadioMenuMsg" "ShowMenu"
}
}
"sourceforts"
{
"Keys"
{
"HudRadioMenuMsg" "ShowMenu"
}
}
"insurgency"
{
"Keys"
{
"HudRadioMenuMsg" "ShowMenu"
}
}
}

View File

@ -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; i<num; i++)
{
if (strcmp(g_SMAPI->GetUserMessage(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();

View File

@ -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:

View File

@ -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;
}

View File

@ -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);

305
core/MenuStyle_Radio.cpp Normal file
View File

@ -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; i<count; i++)
{
g_last_clients[g_last_client_count++] = pFilter->GetRecipientIndex(i);
}
}
void CRadioStyle::OnUserMessageSent(int msg_id)
{
for (unsigned int i=0; i<g_last_client_count; i++)
{
int client = g_last_clients[i];
if (m_players[client].bInMenu)
{
_CancelClientMenu(client, true);
}
m_players[client].bInExternMenu = true;
m_players[client].menuHoldTime = g_last_holdtime;
}
g_last_client_count = 0;
}
void CRadioStyle::SendDisplay(int client, IMenuDisplay *display)
{
CRadioDisplay *rDisplay = (CRadioDisplay *)display;
rDisplay->SendRawDisplay(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"
};

94
core/MenuStyle_Radio.h Normal file
View File

@ -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 <IPlayerHelpers.h>
#include <IUserMessages.h>
#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

View File

@ -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);

View File

@ -235,6 +235,10 @@
RelativePath="..\MenuStyle_Base.cpp"
>
</File>
<File
RelativePath="..\MenuStyle_Radio.cpp"
>
</File>
<File
RelativePath="..\MenuStyle_Valve.cpp"
>
@ -353,6 +357,10 @@
RelativePath="..\MenuStyle_Base.h"
>
</File>
<File
RelativePath="..\MenuStyle_Radio.h"
>
</File>
<File
RelativePath="..\MenuStyle_Valve.h"
>

View File

@ -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;
}

View File

@ -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.
*