Add client_print_color native (CS only) (bug 5823, r=Nextra)

Former-commit-id: 9e37c60bc5
This commit is contained in:
Vincent Herbet 2013-08-24 01:03:13 +02:00
parent ab6644c874
commit af0a1200ab
10 changed files with 209 additions and 1 deletions

View File

@ -316,6 +316,46 @@ void CLangMngr::MergeDefinitions(const char *lang, CQueue<sKeyDef> &tmpVec)
language->MergeDefinitions(tmpVec);
}
void reparse_color(String* def)
{
size_t len = def->size();
int offs = 0;
int c;
if (!len)
return;
for (size_t i = 0; i < len; i++)
{
c = def->at(i);
if (c == '^' && (i != len-1))
{
c = def->at(++i);
if (c >= '1' && c <= '4')
{
switch(c)
{
case '1' : c = '\x01'; break;
case '2' : c = '\x02'; break;
case '3' : c = '\x03'; break;
case '4' : c = '\x04'; break;
}
if (!g_bmod_cstrike) // remove completely these two characters if not under CS
{
offs += 2;
continue;
}
offs++;
}
}
def->at(i-offs, c);
}
def->at(len-offs, '\0');
}
//this is the file parser for dictionary text files
// -- BAILOPAN
int CLangMngr::MergeDefinitionFile(const char *file)
@ -438,6 +478,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
tmpEntry.definition = new String;
tmpEntry.definition->assign(def.c_str());
tmpEntry.definition->trim();
reparse_color(tmpEntry.definition);
tmpEntry.definition->reparse_newlines();
Defq.push(tmpEntry);
tmpEntry.key = -1;
@ -465,6 +506,7 @@ int CLangMngr::MergeDefinitionFile(const char *file)
} else {
if (buf[0] == ':')
{
reparse_color(tmpEntry.definition);
tmpEntry.definition->reparse_newlines();
Defq.push(tmpEntry);
tmpEntry.key = -1;

View File

@ -41,6 +41,7 @@ void CPlayer::Init(edict_t* e, int i)
initialized = false;
ingame = false;
authorized = false;
teamIdsInitialized = false;
current = 0;
teamId = -1;
@ -62,6 +63,7 @@ void CPlayer::Disconnect()
ingame = false;
initialized = false;
authorized = false;
teamIdsInitialized = false;
if (newmenu != -1)
{

View File

@ -85,7 +85,8 @@ public:
bool initialized;
bool ingame;
bool authorized;
bool vgui;
bool vgui;
bool teamIdsInitialized;
float time;
float playtime;

View File

@ -338,6 +338,70 @@ static cell AMX_NATIVE_CALL client_print(AMX *amx, cell *params) /* 3 param */
return len;
}
static cell AMX_NATIVE_CALL client_print_color(AMX *amx, cell *params) /* 3 param */
{
if (!g_bmod_cstrike)
{
params[2] = print_chat;
return client_print(amx, params);
}
int len = 0;
char *msg;
int index = params[1];
int sender = params[2];
if (sender < print_team_blue || sender > gpGlobals->maxClients)
{
sender = print_team_default;
}
else if (sender < print_team_default)
{
sender = abs(sender) + 32; // align indexes to the TeamInfo ones.
}
if (!index)
{
for (int i = 1; i <= gpGlobals->maxClients; ++i)
{
CPlayer *pPlayer = GET_PLAYER_POINTER_I(i);
if (pPlayer->ingame && !pPlayer->IsBot())
{
g_langMngr.SetDefLang(i);
msg = format_amxstring(amx, params, 3, len);
msg[len++] = '\n';
msg[len] = 0;
UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : i, msg);
}
}
}
else
{
if (index < 1 || index > gpGlobals->maxClients)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid player id %d", index);
return 0;
}
CPlayer* pPlayer = GET_PLAYER_POINTER_I(index);
if (pPlayer->ingame && !pPlayer->IsBot())
{
g_langMngr.SetDefLang(index);
msg = format_amxstring(amx, params, 3, len);
msg[len++] = '\n';
msg[len] = 0;
UTIL_ClientSayText(pPlayer->pEdict, sender ? sender : index, msg);
}
}
return len;
}
static cell AMX_NATIVE_CALL show_motd(AMX *amx, cell *params) /* 3 param */
{
int ilen;
@ -4715,6 +4779,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"change_task", change_task},
{"client_cmd", client_cmd},
{"client_print", client_print},
{"client_print_color", client_print_color},
{"console_cmd", console_cmd},
{"console_print", console_print},
{"cvar_exists", cvar_exists},

View File

@ -143,6 +143,8 @@ void UTIL_HudMessage(edict_t *pEntity, const hudtextparms_t &textparms, const ch
void UTIL_IntToString(int value, char *output);
void UTIL_ShowMOTD(edict_t *client, char *motd, int mlen, const char *name);
void UTIL_ShowMenu(edict_t* pEntity, int slots, int time, char *menu, int mlen);
void UTIL_ClientSayText(edict_t *pEntity, int sender, char *msg);
void UTIL_TeamInfo(edict_t *pEntity, int playerIndex, char *pszTeamName);
char *UTIL_VarArgs(const char *fmt, ...);
@ -235,6 +237,8 @@ extern int gmsgWeaponList;
extern int gmsgintermission;
extern int gmsgResetHUD;
extern int gmsgRoundTime;
extern int gmsgSayText;
extern int gmsgInitHUD;
void Client_AmmoPickup(void*);
void Client_AmmoX(void*);
@ -247,6 +251,7 @@ void Client_VGUIMenu(void*);
void Client_WeaponList(void*);
void Client_DamageEnd(void*);
void Client_DeathMsg(void*);
void Client_InitHUDEnd(void*);
void amx_command();
void plugin_srvcmd();
@ -353,6 +358,14 @@ enum AdminProperty
Admin_Flags
};
enum PrintColor
{
print_team_default = 0,
print_team_grey =-1,
print_team_red = -2,
print_team_blue = -3,
};
extern enginefuncs_t *g_pEngTable;
#endif // AMXMODX_H

View File

@ -52,6 +52,8 @@ int gmsgWeaponList;
int gmsgintermission;
int gmsgResetHUD;
int gmsgRoundTime;
int gmsgSayText;
int gmsgInitHUD;
TeamIds g_teamsIds;
WeaponsVault g_weaponsData[MAX_WEAPONS];
@ -328,6 +330,26 @@ void Client_DeathMsg(void* mValue)
victim->death_tk = (killer->teamId == victim->teamId);
}
}
void Client_InitHUDEnd(void* mValue)
{
if (!g_bmod_cstrike)
return;
CPlayer *pPlayer = mPlayer;
if (!pPlayer->teamIdsInitialized && !pPlayer->IsBot())
{
// This creates specific indexes (> maxplayers) for print_chat_color().
// 33 : print_team_grey / spectator
// 34 : print_team_red / terrorist
// 35 : print_team_blue / ct
UTIL_TeamInfo(pPlayer->pEdict, 33 + 1, "TERRORIST"); // print_team_red
UTIL_TeamInfo(pPlayer->pEdict, 33 + 2, "CT"); // print_team_blue
pPlayer->teamIdsInitialized = true;
}
}
/*
void Client_SendAudio(void* mValue)
{

View File

@ -564,6 +564,8 @@ struct sUserMsg
{"WeapPickup", &gmsgWeapPickup, 0, false, false},
{"ResetHUD", &gmsgResetHUD, 0, false, false},
{"RoundTime", &gmsgRoundTime, 0, false, false},
{"SayText", &gmsgSayText, 0, false, false},
{"InitHUD", &gmsgInitHUD, Client_InitHUDEnd, true, false},
{0, 0, 0, false, false}
};

View File

@ -294,6 +294,32 @@ void UTIL_ClientPrint(edict_t *pEntity, int msg_dest, char *msg)
msg[190] = c;
}
void UTIL_ClientSayText(edict_t *pEntity, int sender, char *msg)
{
if (!gmsgSayText)
return; // :TODO: Maybe output a warning log?
char c = msg[190];
msg[190] = 0; // truncate without checking with strlen()
MESSAGE_BEGIN(MSG_ONE, gmsgSayText, NULL, pEntity);
WRITE_BYTE(sender);
WRITE_STRING(msg);
MESSAGE_END();
msg[190] = c;
}
void UTIL_TeamInfo(edict_t *pEntity, int playerIndex, char *pszTeamName)
{
if (!gmsgTeamInfo)
return;
MESSAGE_BEGIN(MSG_ONE, gmsgTeamInfo, NULL, pEntity);
WRITE_BYTE(playerIndex);
WRITE_STRING(pszTeamName);
MESSAGE_END();
}
// UTIL_FakeClientCommand
// PURPOSE: Sends a fake client command to GameDLL
// HOW DOES IT WORK:

View File

@ -175,6 +175,14 @@ enum {
print_center,
};
/* Color types for client_print_color() */
enum {
print_team_default = 0,
print_team_grey = -1,
print_team_red = -2,
print_team_blue = -3,
};
/* Destination types for engclient_print() */
enum {
engprint_console = 0,

View File

@ -102,6 +102,33 @@ native show_motd(player,const message[],const header[]="");
/* Sends message to player. Set index to 0 to send text globaly. */
native client_print(index,type,const message[],any:...);
/**
* Sends colored message to player. Set index to 0 to send text globally.
* This works only under Counter-Strike 1.6 and Counter-Strike: Condition Zero.
*
* The available colors identifiers are :
* green ^4 ; use location color from this point forward
* red/blue/grey ^3 ; use team color from this point forward
* red/blue/grey ^2 ; use team color up to the end of the player name. This only works at the start of the string, and precludes using the other control characters.
* normal ^1 ; use normal color from this point forward
*
* The team color is defined either with a sender's index, or a specific team color using print_team_* constants (print_team_blue, print_team_red, print_team_grey).
* A message must start with a default color.
*
* An example would be: client_print_color(id, print_team_red, "^4This is green ^3this is red, ^1this is your default chat text color");
* Another with index : client_print_color(id, idOther, "^4This is green ^3this idOther's team color, ^1this is your default chat text color");
* In multilingual file : KEY = ^1This is normal color, ^4this is green, ^1normal again ^3and now team color.
*
* @param index This is the player index (1 to maxplayer) you want to send the message, use 0 to send to all players.
* @param sender This is the player index you want to use the team color, see print_team_* constants if you want to force a color.
* @param fmt Format string in which patterns gonna be replaced with argument list.
*
* @return 1 if the message has been sent,
* 0 if the index specified is a not connected player,
* or if a global message has not been sent because there are no humans players.
*/
native client_print_color(index, sender, const message[], any:...);
/* Sends message to player by engine. Set index to 0 to send text globaly. */
native engclient_print(player,type,const message[],any:...);