Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
|
01-07-2016
, 13:11
Re: Using print color function with 'LANG_PLAYER' on Amx Mod X 1.8.2
|
#2
|
A more elaborated failure with macros | go to top
Spoiler
Code:
#include <amxmodx>
#include <amxmisc>
#define COLOR_MESSAGE 192
new bool:g_is_color_chat_supported
#if AMXX_VERSION_NUM < 183
#define LANG_PLAYER_COLORED g_colored_players_ids[ g_colored_current_index ]
/**
* Print colored text to a given player_id. You can call this function using the player_id as 0,
* to display the colored message to all players on the server. Use 'LANG_PLAYER_COLORED' instead
* of 'LANG_PLAYER' to display a message to all player on the server using the player_id as 0.
*
* Do not use semicolon ';' after call this macro, even if you have enabled the semicolon.
* Usage example for AMX Mod X 1.8.2 or superior:
* @code{.cpp}
* PRINT_COLORED_TEXT( 0, "^1Hi^4 from %L!", LANG_PLAYER_COLORED, "LANG_USER_COUNTRY" )
*
* PRINT_COLORED_TEXT( player_id, "^1Hi^4 from %L!", player_id, "LANG_USER_COUNTRY" )
* @endcode
*
* If you run this function on a Game Mod that do not support colored messages, they will be
* displayed as normal messages without any errors or bad formats.
*
* This allow you to use '!g for green', '!y for yellow', '!t for team' color with LANGs file
* using the register_dictionary_colored file. Otherwise use '^1', '^2', '^3' and '^4'.
*
* @param player_id the player id.
* @param message[] the text formatting rules to display.
* @param any the variable number of formatting parameters.
*/
#define PRINT_COLORED_TEXT(%1) \
{ \
print_colored_configure( %1 ); \
if( g_colored_player_id ) \
{ \
client_print_color_internal( %1 ); \
} \
else \
{ \
get_players( g_colored_players_ids, g_colored_players_number, "ch" ); \
for( g_colored_current_index = 0; g_colored_current_index < g_colored_players_number; \
g_colored_current_index++ ) \
{ \
client_print_color_internal( %1 ); \
} \
} \
}
new g_user_msgid
new g_colored_player_id
new g_colored_players_number
new g_colored_current_index
new g_colored_players_ids[ 32 ]
stock print_colored_configure( player_id, any:... )
{
g_colored_player_id = player_id;
}
#else
#define LANG_PLAYER_COLORED LANG_PLAYER
#define PRINT_COLORED_TEXT(%1) client_print_color_internal( %1 );
#endif
stock client_print_color_internal( player_id, message[], any: ... )
{
new formated_message[ COLOR_MESSAGE ]
vformat( formated_message, charsmax( formated_message ), message, 3 )
if( g_is_color_chat_supported )
{
#if AMXX_VERSION_NUM < 183
message_begin( MSG_ONE_UNRELIABLE, g_user_msgid, _, player_id );
write_byte( player_id );
write_string( formated_message );
message_end();
#else
client_print_color( player_id, print_team_default, formated_message )
#endif
}
else
{
replace_all( formated_message, charsmax( formated_message ), "^1", "" );
replace_all( formated_message, charsmax( formated_message ), "^2", "" );
replace_all( formated_message, charsmax( formated_message ), "^3", "" );
replace_all( formated_message, charsmax( formated_message ), "^4", "" );
client_print( player_id, print_chat, formated_message )
}
}
/**
* Called just before server deactivation and subsequent unloading of the
* plugin.
*/
public plugin_cfg()
{
register_dictionary_colored( "your_dictionary_colored.txt" );
#if AMXX_VERSION_NUM < 183
g_user_msgid = get_user_msgid( "SayText" )
#endif
PRINT_COLORED_TEXT( 0, "^1Hi^4 from %L!", LANG_PLAYER_COLORED, "LANG_USER_COUNTRY" )
g_is_color_chat_supported = ( is_running( "czero" )
|| is_running( "cstrike" ) )
}
/**
* ConnorMcLeod's [Dyn Native] ColorChat v0.3.2 (04 jul 2013) register_dictionary_colored function:
* <a href="https://forums.alliedmods.net/showthread.php?p=851160">ColorChat v0.3.2</a>
*
* @param filename the dictionary file name including its file extension.
*/
stock register_dictionary_colored( const filename[] )
{
if( !register_dictionary( filename ) )
{
return 0;
}
new szFileName[ 256 ];
get_localinfo( "amxx_datadir", szFileName, charsmax( szFileName ) );
format( szFileName, charsmax( szFileName ), "%s/lang/%s", szFileName, filename );
new fp = fopen( szFileName, "rt" );
if( !fp )
{
log_amx( "Failed to open %s", szFileName );
return 0;
}
new szBuffer[ 512 ], szLang[ 3 ], szKey[ 64 ], szTranslation[ 256 ], TransKey:iKey;
while( !feof( fp ) )
{
fgets( fp, szBuffer, charsmax( szBuffer ) );
trim( szBuffer );
if( szBuffer[ 0 ] == '[' )
{
strtok( szBuffer[ 1 ], szLang, charsmax( szLang ), szBuffer, 1, ']' );
}
else if( szBuffer[ 0 ] )
{
#if AMXX_VERSION_NUM < 183
strbreak( szBuffer, szKey, charsmax( szKey ), szTranslation, charsmax( szTranslation ) );
#else
argbreak( szBuffer, szKey, charsmax( szKey ), szTranslation, charsmax( szTranslation ) );
#endif
iKey = GetLangTransKey( szKey );
if( iKey != TransKey_Bad )
{
replace_all( szTranslation, charsmax( szTranslation ), "!g", "^4" );
replace_all( szTranslation, charsmax( szTranslation ), "!t", "^3" );
replace_all( szTranslation, charsmax( szTranslation ), "!n", "^1" );
replace_all( szTranslation, charsmax( szTranslation ), "!y", "^1" );
AddTranslation( szLang, iKey, szTranslation[ 2 ] );
}
}
}
fclose( fp );
return 1;
}
Full Working Example | go to top
Spoiler
Code:
#include <amxmodx>
#include <amxmisc>
#define MAX_COLOR_MESSAGE 192
#if AMXX_VERSION_NUM < 183
new g_user_msgid
new g_colored_player_id
new g_colored_players_number
new g_colored_current_index
new g_colored_players_ids[ 32 ]
#endif
new g_coloredChatPrefix[ 16 ] = "^4[^1AMXX^4]"
new bool:g_is_color_chat_supported
/**
* Convert colored strings codes '!g for green', '!y for yellow', '!t for team'.
*/
#define INSERT_COLOR_TAGS(%1) \
{ \
replace_all( %1, charsmax( %1 ), "!g", "^4" ); \
replace_all( %1, charsmax( %1 ), "!t", "^3" ); \
replace_all( %1, charsmax( %1 ), "!n", "^1" ); \
replace_all( %1, charsmax( %1 ), "!y", "^1" ); \
}
#define REMOVE_COLOR_TAGS(%1) \
{ \
replace_all( %1, charsmax( %1 ), "^1", "" ); \
replace_all( %1, charsmax( %1 ), "^2", "" ); \
replace_all( %1, charsmax( %1 ), "^3", "" ); \
replace_all( %1, charsmax( %1 ), "^4", "" ); \
}
#define PRINT_COLORED_MESSAGE(%1,%2) \
{ \
message_begin( MSG_ONE_UNRELIABLE, g_user_msgid, _, %1 ); \
write_byte( %1 ); \
write_string( %2 ); \
message_end(); \
}
public plugin_init()
{
register_plugin( "New Plug-In", "1.0", "Author" );
register_clcmd( "say test", "test" );
}
public plugin_cfg()
{
g_is_color_chat_supported = ( is_running( "czero" ) || is_running( "cstrike" ) )
#if AMXX_VERSION_NUM < 183
g_user_msgid = get_user_msgid( "SayText" )
#endif
register_dictionary_colored( "your_dictionary_colored.txt" );
}
public test()
{
#if AMXX_VERSION_NUM < 183
get_players( g_colored_players_ids, g_colored_players_number, "ch" );
for( g_colored_current_index = 0; g_colored_current_index < g_colored_players_number;
g_colored_current_index++ )
{
g_colored_player_id = g_colored_players_ids[ g_colored_current_index ]
color_print( g_colored_player_id, "^1%L", g_colored_player_id, "CMD_MENU" ) // here, use g_colored_player_id instead of LANG_PLAYER
}
#else
client_print_color( 0, print_team_default, "^1%L", LANG_PLAYER, "CMD_MENU" ) // here, use LANG_PLAYER
#endif
#if AMXX_VERSION_NUM < 183
color_print( 0, "Message: ^4%L", LANG_PLAYER, "CMD_MENU" );
#else
client_print_color( 0, print_team_default, "Message: ^4%L", LANG_PLAYER, "CMD_MENU" ); // here, use LANG_PLAYER
#endif
}
/**
* Print colored text to a given player_id. It has to be called to each player using its player_id
* instead of 'LANG_PLAYER' constant. Just use the 'LANG_PLAYER' constant when using this function
* to display to all players.
*
* This includes the code:
* ConnorMcLeod's [Dyn Native] ColorChat v0.3.2 (04 jul 2013) register_dictionary_colored function:
* <a href="https://forums.alliedmods.net/showthread.php?p=851160">ColorChat v0.3.2</a>
*
* If you run this function on a Game Mod that do not support colored messages, they will be
* displayed as normal messages without any errors or bad formats.
*
* This allow you to use '!g for green', '!y for yellow', '!t for team' color with LANGs at a
* register_dictionary_colored file. Otherwise use '^1', '^2', '^3' and '^4'.
*
* @param player_id the player id.
* @param lang_formatting the text formatting rules to display.
* @param any the variable number of formatting parameters.
*
* @see <a href="https://www.amxmodx.org/api/amxmodx/client_print_color">client_print_color</a>
* @see <a href="https://forums.alliedmods.net/showthread.php?t=297484">vformat() ignoring user language</a>
*/
stock color_print( const player_id, const lang_formatting[], any:... )
{
new formatted_message[ MAX_COLOR_MESSAGE ];
if( player_id )
{
if( g_is_color_chat_supported )
{
// Here all the colored messaged must to start within a color.
formatted_message[ 0 ] = '^1';
vformat( formatted_message[ 1 ], charsmax( formatted_message ) - 1, lang_formatting, 3 );
if( g_coloredChatPrefix[ 0 ] )
{
new message[ MAX_COLOR_MESSAGE ];
formatex( message, charsmax( message ), "^1%s^1%s", g_coloredChatPrefix, formatted_message[ 1 ] );
PRINT_COLORED_MESSAGE( player_id, message )
}
else
{
PRINT_COLORED_MESSAGE( player_id, formatted_message )
}
}
else
{
vformat( formatted_message, charsmax( formatted_message ), lang_formatting, 3 );
REMOVE_COLOR_TAGS( formatted_message )
client_print( player_id, print_chat, "%s%s", g_coloredChatPrefix, formatted_message );
}
}
else
{
new playersCount;
new players[ MAX_PLAYERS ];
// Get the server players skipping the bots
get_players( players, playersCount, "c" );
// Figure out if at least 1 player is connected, so we don't execute useless code
if( !playersCount )
{
return;
}
new player_id;
new string_index;
new argument_index;
new multi_lingual_constants_number;
new params_number;
new Array:multi_lingual_indexes_array;
multi_lingual_indexes_array = ArrayCreate();
params_number = numargs();
multi_lingual_constants_number = 0;
// ML can be used
if( params_number > 3 )
{
for( argument_index = 2; argument_index < params_number; argument_index++ )
{
// retrieve original param value and check if it's LANG_PLAYER value
if( getarg( argument_index ) == LANG_PLAYER )
{
string_index = 0;
// as LANG_PLAYER == -1, check if next param string is a registered language translation
while( ( formatted_message[ string_index ] =
getarg( argument_index + 1, string_index++ ) ) )
{
}
formatted_message[ string_index ] = '^0';
if( GetLangTransKey( formatted_message ) != TransKey_Bad )
{
// Store that argument as LANG_PLAYER so we can alter it later
ArrayPushCell( multi_lingual_indexes_array, argument_index++ );
// Update ML array, so we'll know 1st if ML is used, 2nd how many arguments we have to change
multi_lingual_constants_number++;
}
}
}
}
for( --playersCount; playersCount >= 0; --playersCount )
{
player_id = players[ playersCount ];
if( multi_lingual_constants_number )
{
for( argument_index = 0; argument_index < multi_lingual_constants_number; argument_index++ )
{
// Set all LANG_PLAYER args to player index ( = player_id ), so we can format the text for that specific player
setarg( ArrayGetCell( multi_lingual_indexes_array, argument_index ), _, player_id );
}
}
if( g_is_color_chat_supported )
{
// Here all the colored messaged must to start within a color.
formatted_message[ 0 ] = '^1';
vformat( formatted_message[ 1 ], charsmax( formatted_message ) - 1, lang_formatting, 3 );
if( g_coloredChatPrefix[ 0 ] )
{
new message[ MAX_COLOR_MESSAGE ];
formatex( message, charsmax( message ), "^1%s^1%s", g_coloredChatPrefix, formatted_message[ 1 ] );
PRINT_COLORED_MESSAGE( player_id, message )
}
else
{
PRINT_COLORED_MESSAGE( player_id, formatted_message )
}
}
else
{
vformat( formatted_message, charsmax( formatted_message ), lang_formatting, 3 );
REMOVE_COLOR_TAGS( formatted_message )
client_print( player_id, print_chat, "%s%s", g_coloredChatPrefix, formatted_message );
}
}
ArrayDestroy( multi_lingual_indexes_array );
}
}
/**
* ConnorMcLeod's [Dyn Native] ColorChat v0.3.2 (04 jul 2013) register_dictionary_colored function:
* <a href="https://forums.alliedmods.net/showthread.php?p=851160">ColorChat v0.3.2</a>
*
* @param filename the dictionary file name including its file extension.
*/
stock register_dictionary_colored( const filename[] )
{
if( !register_dictionary( filename ) )
{
return 0;
}
new szFileName[ 256 ];
get_localinfo( "amxx_datadir", szFileName, charsmax( szFileName ) );
format( szFileName, charsmax( szFileName ), "%s/lang/%s", szFileName, filename );
new fp = fopen( szFileName, "rt" );
if( !fp )
{
log_amx( "Failed to open %s", szFileName );
return 0;
}
new szBuffer[ 512 ], szLang[ 3 ], szKey[ 64 ], szTranslation[ 256 ], TransKey:iKey;
while( !feof( fp ) )
{
fgets( fp, szBuffer, charsmax( szBuffer ) );
trim( szBuffer );
if( szBuffer[ 0 ] == '[' )
{
strtok( szBuffer[ 1 ], szLang, charsmax( szLang ), szBuffer, 1, ']' );
}
else if( szBuffer[ 0 ] )
{
#if AMXX_VERSION_NUM < 183
strbreak( szBuffer, szKey, charsmax( szKey ), szTranslation, charsmax( szTranslation ) );
#else
argbreak( szBuffer, szKey, charsmax( szKey ), szTranslation, charsmax( szTranslation ) );
#endif
iKey = GetLangTransKey( szKey );
if( iKey != TransKey_Bad )
{
INSERT_COLOR_TAGS( szTranslation )
AddTranslation( szLang, iKey, szTranslation[ 2 ] );
}
}
}
fclose( fp );
return 1;
}
# Update 05/2017
I managed to create the macro, but it has the downfall to not allow insert prefixes on the message: - vformat() ignoring user language on AMXX 183 build 5116#postcount=8
__________________
Last edited by addons_zz; 05-25-2017 at 17:03.
Reason: A more elaborated fail
|
|