// Should the plugin save player data in SQL database?
// To save player data in a vault, change "#define USING_SQL" to "//#define USING_SQL"
// To save player data in SQL, change "//#define USING_SQL" to "#define USING_SQL"
// If you comment //#define USING_REGEX its a little bit more non-steam friendly
//#define USING_SQL
#define USING_REGEX
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if defined USING_REGEX
#include
#endif
#if defined USING_SQL
#include
new Handle:g_sql_tuple
#else
#include
new g_iVault
#endif
#if defined USING_SQL
new g_loaded_data[ 33 ]
#endif
#define VERSION "1.9"
#define XO_PLAYER 5
#define m_pPlayer 41
#define m_fInReload 54
#define m_fInSpecialReload 55
#define m_flTimeWeaponIdle 48
#define m_flFlashedUntil 514
#define m_flFlashedAt 515
#define m_flFlashHoldTime 516
#define m_flFlashDuration 517
#define m_iFlashAlpha 518
#define ALPHA_FULLBLINDED 255
#define INTERVAL 60
new g_iMaxPlayers
#define IsPlayer(%1) (1 <= %1 <= g_iMaxPlayers)
const MAX_PLAYERS = 32
const MAX_WEAPONS = CSW_P90
new g_iMsgId_SayText, g_iBombTime,
g_iPlanter, g_iGetBombPlanted
new const g_szAchievementSound[] = "achievement.wav"
new const Float:vecNullOrigin[ 3 ]
new Float:flDistance[ MAX_PLAYERS + 1 ],
Float:vecOldOrigin[ MAX_PLAYERS + 1 ][ 3 ],
Float:g_iFeet = 35.0
new g_iRounds, g_fwid
new g_iTeamKills[ 33 ], g_iRoundSparys[ 33 ],
g_iKills[ 33 ], g_iShotKills[ 33 ],
g_iGrenadeKills[ 33 ]
new bool:g_iBombPlant, bool:g_bFeet, bool:is_dead[ 33 ],
bool:StandAlone[ 33 ], bool:OneHpHero[ 33 ],
bool:is_VictimInAir[ 33 ], bool:iKillerHasNotMoved[ 33 ],
bool:iKillerShot[ 33 ], bool:is_Connected[ 33 ],
bool:is_Alive[ 33 ], bool:is_DefusingWithKit,
bool:g_iGetBombDown, bool:g_iDeathMessages[ 33 ]
new g_iHelpMotd[ 43 ]
#if defined USING_REGEX
new Regex:g_SteamID_pattern
new g_regex_return
#endif
enum _:g_iAchCount
{
CONNECTIONS,
HEAD_SHOTS,
DISTANCE_KILLED,
DISTANCE_WALKED,
BOMB,
PLANT_BOMB,
PLANT_BOMB_COUNT,
DEFUSED_BOMB,
TOTAL_KILLS,
PISTOL_MASTER,
RIFLE_MASTER,
SHOTGUN_MASTER,
SPRAY_N_PRAY,
MASTER_AT_ARMS,
PLAY_AROUND,
STAND_ALONE,
ONE_HP_HERO,
BAD_FRIEND,
URBAN_DESIGNER,
GRAFFITI,
AMMO_CONSERVATION,
FLY_AWAY,
RELOADER,
CAMP_FIRE,
HAT_TRICK,
COWBOY_DIPLOMACY
}
new const g_iAchsMotd[g_iAchCount][] =
{
"Ultimate Server Lover",
"Boom Head-Shot",
"Distance Killed",
"Distance Walked",
"Oh! , that was too close",
"Short Fuse",
"Boomala Boomala",
"Nothing Can Blow Up",
"God of War",
"Pistol Master",
"Rifle Master",
"Shotgun Master",
"Spray and Pray",
"Master At Arms",
"Play Around",
"Stand Alone",
"1 Hp Hero",
"Bad Friend",
"Urban Designer",
"Graffiti Is My Second Name",
"Ammo Conservation",
"Fly Away",
"Reloader",
"Camp Fire",
"Hat Trick",
"Cowboy Diplomacy"
}
new const g_iAchsMaxPoints[g_iAchCount] =
{
1000, // Connections
300, // Headshots
4, // distance killed
3, // distance walk
1, // bomb
1, // Plant bomb
100, // plant bomb count
400, // Defused Bomb
10000, // total kills
6, // Pistol master
10, // rifle Master
2, // shotgun master
1, // spray and pray
25, // Master of Arms
60, // Play Around
15, // Stand Alone
1, // 1 Hp Hero
5, // Bad Friend
300, // Urban Designer
1, // Graffiti Is My Second Name
1, // Ammo Conservation
1, // Fly way
1000, // Reloader
1, // Camp Fire
1, // HatTrick
100 // Cowboy Diplomacy
}
new g_iAuthID[ 33 ][ 36 ]
//Cvars
new g_pCvar_Enabled, g_pCvarC4Timer,
g_pCvar_ShowInfo, g_pCvar_DeathMessage,
g_pCvar_FlashMessage, g_pCvar_BombMessage
//g_pCvar_FriendlyFire
new const g_szWeaponNames[][] =
{
"p228",
"scout",
"hegrenade",
"xm1014",
"c4",
"mac10",
"aug",
"smokegrenade",
"elite",
"fiveseven",
"ump45",
"sg550",
"galil",
"famas",
"usp",
"glock18",
"awp",
"mp5navy",
"m249",
"m3",
"m4a1",
"tmp",
"g3sg1",
"flashbang",
"deagle",
"sg552",
"ak47",
"knife",
"p90"
}
#define WEAPON_SIZE sizeof(g_szWeaponNames)
new const g_iWeaponIDs[WEAPON_SIZE] =
{
CSW_P228,
CSW_SCOUT,
CSW_HEGRENADE,
CSW_XM1014,
CSW_C4,
CSW_MAC10,
CSW_AUG,
CSW_SMOKEGRENADE,
CSW_ELITE,
CSW_FIVESEVEN,
CSW_UMP45,
CSW_SG550,
CSW_GALIL,
CSW_FAMAS,
CSW_USP,
CSW_GLOCK18,
CSW_AWP,
CSW_MP5NAVY,
CSW_M249,
CSW_M3,
CSW_M4A1,
CSW_TMP,
CSW_G3SG1,
CSW_FLASHBANG,
CSW_DEAGLE,
CSW_SG552,
CSW_AK47,
CSW_KNIFE,
CSW_P90
}
new const g_iAchsWeaponMaxKills[] =
{
200, //"p228",
1000, //"scout",
300, //"hegrenade",
200, //"xm1014",
30, //"c4",
500, //"mac10",
500, //"aug",
150, //"smokegrenade",
100, //"elite",
100, //"fiveseven",
1000, //"ump45",
500, //"sg550",
500, //"galil",
500, //"famas",
200, //"usp",
200, //"glock18",
1000, //"awp",
1000, //"mp5navy",
500, //"m249",
200, //"m3",
1000, //"m4a1",
1000, //"tmp",
500, //"g3sg1",
150, //"flashbang",
200, //"deagle",
500, //"sg552",
1000, //"ak47",
200, //"knife",
1000 //"p90"
}
new const g_szWeaponNames2[WEAPON_SIZE][] =
{
"P228",
"Scout",
"He-Grenade",
"XM1014",
"C4",
"Mac10",
"Aug",
"Smoke-Grenade",
"Elite",
"Fiveseven",
"Ump45",
"SG550",
"Galil",
"Famas",
"USP",
"Glock",
"AWP",
"MP5",
"M249",
"M3",
"M4A1",
"TMP",
"G3SG1",
"FlashBang",
"Deagle",
"SG552",
"AK47",
"Knife",
"P90"
}
new const g_iGunEvents[][] = {
"events/awp.sc",
"events/g3sg1.sc",
"events/ak47.sc",
"events/scout.sc",
"events/m249.sc",
"events/m4a1.sc",
"events/sg552.sc",
"events/aug.sc",
"events/sg550.sc",
"events/m3.sc",
"events/xm1014.sc",
"events/usp.sc",
"events/mac10.sc",
"events/ump45.sc",
"events/fiveseven.sc",
"events/p90.sc",
"events/deagle.sc",
"events/p228.sc",
"events/glock18.sc",
"events/mp5n.sc",
"events/tmp.sc",
"events/elite_left.sc",
"events/elite_right.sc",
"events/galil.sc",
"events/famas.sc"
}
new g_iPlayersKills[ MAX_PLAYERS+1 ][ MAX_WEAPONS+1 ]
new g_iAchLevel[ MAX_PLAYERS+1 ][ g_iAchCount ]
new g_iTimerEntity, g_iJoinTime[ MAX_PLAYERS ]
new Trie:g_tWeaponNameToID
new iWeaponID, g_iGunEvent_IDsBitsum
public plugin_init() {
#if defined USING_SQL
register_plugin( "Achievements (SQL)", VERSION, "!Pastout!!" )
#else
register_plugin( "Achievements", VERSION, "!Pastout!!" )
#endif
g_pCvar_Enabled = register_cvar("ach_enable", "1")// 1 = on || 0 = off
if ( !get_pcvar_num( g_pCvar_Enabled ) )
return;
g_pCvarC4Timer = get_cvar_pointer( "mp_c4timer" )
g_pCvar_ShowInfo = register_cvar( "ach_showinfo", "1" )
g_pCvar_DeathMessage = register_cvar( "ach_deathmessage", "1" )
g_pCvar_FlashMessage = register_cvar( "ach_flashmessage", "1" )
g_pCvar_BombMessage = register_cvar( "ach_bombmessage", "1" )
//g_pCvar_FriendlyFire = get_cvar_pointer( "mp_friendlyfire" )
new command[] = "CmdMainMenu"
register_clcmd( "say /achievement", command )
register_clcmd( "say /achievements", command )
register_clcmd( "say /ach", command )
register_clcmd( "say /help", "Ach_HelpMenu" )
register_clcmd( "say /deathmessage", "CmdDeathMessage" )
register_event( "DeathMsg", "Event_PlayerKilled", "a" )
register_event( "HLTV", "Event_NewRound", "a", "1=0", "2=0" )
register_event( "StatusIcon", "Event_GotBomb", "be", "1=1", "1=2", "2=c4" )
register_event( "ResetHUD", "Event_ResetHud", "be" )
register_event( "23", "Event_Spray", "a", "1=112" )
register_logevent( "Event_PlayerAction", 3, "1=triggered" )
g_iTimerEntity = create_entity( "info_target" )
entity_set_string( g_iTimerEntity, EV_SZ_classname, "hud_entity" )
register_think( "hud_entity", "fw_HUDThink" )
entity_set_float( g_iTimerEntity, EV_FL_nextthink, get_gametime() + 1.0 )
g_iMaxPlayers = get_maxplayers()
g_iMsgId_SayText = get_user_msgid( "SayText" )
g_tWeaponNameToID = TrieCreate()
for( new i = 0; i < WEAPON_SIZE; i++ )
{
TrieSetCell( g_tWeaponNameToID, g_szWeaponNames[i], g_iWeaponIDs[i] )
}
new const NO_RELOAD = ( 1 << 2 ) | ( 1 << CSW_KNIFE ) | ( 1 << CSW_C4 ) | ( 1 << CSW_M3 ) |
( 1 << CSW_XM1014 ) | ( 1 << CSW_HEGRENADE ) | ( 1 << CSW_FLASHBANG ) | ( 1 << CSW_SMOKEGRENADE )
new szWeaponName[ 20 ]
for( new i = CSW_P228; i <= CSW_P90; i++ ) {
if( NO_RELOAD & ( 1 << i ) )
continue;
get_weaponname( i, szWeaponName, 19 )
RegisterHam( Ham_Weapon_Reload, szWeaponName, "FwdHamWeaponReload", 1 )
}
RegisterHam( Ham_Weapon_Reload, "weapon_m3", "FwdHamShotgunReload", 1 )
RegisterHam( Ham_Weapon_Reload, "weapon_xm1014", "FwdHamShotgunReload", 1 )
RegisterHam( Ham_TraceAttack, "player", "FwdHamTraceAttack" )
RegisterHam( Ham_Spawn, "player", "FwdPlayerSpawn", 1 )
unregister_forward( FM_PrecacheEvent, g_fwid, 1 )
register_forward( FM_PlaybackEvent, "FwdPlaybackEvent" )
register_forward( FM_CmdStart, "FwdCmdStart" )
new dir[ 23 ]
get_configsdir( dir, 22 )
formatex( g_iHelpMotd, 42, "%s/achievements.txt", dir )
#if !defined USING_SQL
g_iVault = nvault_open("Achievements")
if(g_iVault == INVALID_HANDLE)
set_fail_state( "Error opening nVault" )
#endif
#if defined USING_REGEX
new err[ 2 ]
g_SteamID_pattern = regex_compile( "^^STEAM_0:(0|1):\d+$", g_regex_return, err, sizeof( err ) - 1 )
#endif
}
public Event_PlayerAction( )
{
new szArg[ 64 ], szAction[ 64 ], szName[ 64 ]
new iUserId, id
read_logargv( 0, szArg, 64 )
read_logargv( 2, szAction, 64 )
parse_loguser( szArg, szName, 64, iUserId )
id = find_player( "k", iUserId )
if( id == 0 )
{
return
}
#if defined USING_REGEX
if( !IsUserAuthorized( id ) )
{
return
}
#endif
if( equal( szAction, "Rescued_A_Hostage" ) )
{
g_iAchLevel[ id ][ COWBOY_DIPLOMACY ]++
switch( g_iAchLevel[ id ][ COWBOY_DIPLOMACY ] )
{
case 100:
{
g_iAchLevel[ id ][ COWBOY_DIPLOMACY ]++
Print( 0, "%s^1 has earned ^3'^1Cowboy Diplomacy^3'^4 achievement!", szName )
emit_sound( id, CHAN_STATIC, g_szAchievementSound, 1.0, ATTN_NORM, 0, PITCH_NORM )
}
}
Print( 0, "%s^1 has^4 rescued^1 a^3 Hostage^1.", szName )// Hostage rescued
}
if( get_pcvar_num( g_pCvar_BombMessage ) == 1 )
{
if( equal( szAction, "Begin_Bomb_Defuse_With_Kit" ) )
{
is_DefusingWithKit = true
}
}
#if defined USING_REGEX
return
#endif
}
public FwdHamWeaponReload( const iWeapon ) {
new iPlayers[ 32 ], iNum, iPlayer
get_players(iPlayers, iNum, "ah")
for( new i = 0; i < iNum; i++ )
{
iPlayer = iPlayers[ i ]
}
#if defined USING_REGEX
if( !IsUserAuthorized( iPlayer ) )
{
return
}
#endif
new szName[ 32 ]
get_user_name( iPlayer, szName, charsmax( szName ) )
if( get_pdata_int( iWeapon, m_fInReload, 4 ) ) {
g_iAchLevel[ iPlayer ][ RELOADER ]++
switch( g_iAchLevel[ iPlayer ][ RELOADER ] )
{
case 1000:
{
g_iAchLevel[ iPlayer ][ RELOADER ]++
Print( 0, "%s^1 has earned ^3'^1Reloader^3'^4 achievement!", szName )
emit_sound( iPlayer, CHAN_STATIC, g_szAchievementSound, 1.0, ATTN_NORM, 0, PITCH_NORM )
}
}
}
#if defined USING_REGEX
return
#endif
}
public FwdHamShotgunReload( const iWeapon ) {
if( get_pdata_int( iWeapon, m_fInSpecialReload, 4 ) != 1 )
return
new Float:flTimeWeaponIdle = get_pdata_float( iWeapon, m_flTimeWeaponIdle, 4 )
if( flTimeWeaponIdle != 0.55 )
return
new iPlayers[ 32 ], iNum, iPlayer
get_players(iPlayers, iNum, "ah")
for( new i = 0; i < iNum; i++ )
{
iPlayer = iPlayers[ i ]
}
#if defined USING_REGEX
if( !IsUserAuthorized( iPlayer ) )
{
return
}
#endif
new szName[ 32 ]
get_user_name( iPlayer, szName, charsmax( szName ) )
g_iAchLevel[ iPlayer ][ RELOADER ]++
switch( g_iAchLevel[ iPlayer ][ RELOADER ] )
{
case 1000:
{
g_iAchLevel[ iPlayer ][ RELOADER ]++
Print( 0, "%s^1 has earned ^3'^1Reloader^3'^4 achievement!", szName )
emit_sound( iPlayer, CHAN_STATIC, g_szAchievementSound, 1.0, ATTN_NORM, 0, PITCH_NORM )
}
}
#if defined USING_REGEX
return
#endif
}
public fw_HUDThink( iEntity )
{
if ( iEntity != g_iTimerEntity )
return
static id
new szName[ 32 ]
for ( id = 1; id <= MAX_PLAYERS; id++ )
{
if ( is_user_connected( id ) && ( ( get_systime() - g_iJoinTime[ id ] ) >= INTERVAL ) )
{
#if defined USING_REGEX
if( !IsUserAuthorized( id ) )
{
return
}
#endif
get_user_name( id, szName, charsmax( szName ) )
g_iJoinTime[ id ] = get_systime()
g_iAchLevel[ id ][ PLAY_AROUND ]++
switch( g_iAchLevel[ id ][ PLAY_AROUND ] )
{
case 60:
{
g_iAchLevel[ id ][ PLAY_AROUND ]++
Print( 0, "%s^1 has earned ^3'^1Play Around^3'^4 achievement!", szName )
emit_sound( id, CHAN_STATIC, g_szAchievementSound, 1.0, ATTN_NORM, 0, PITCH_NORM )
}
}
#if defined USING_REGEX
return
#endif
}
}
entity_set_float( g_iTimerEntity, EV_FL_nextthink, get_gametime() + 1.0 )
}
public CmdDeathMessage( id )
{
if( get_pcvar_num( g_pCvar_DeathMessage ) != 1 )
{
Print( id, "^3Sorry^1 the^4 death message^1 have been^4 disable^1 for^3 everyone." )
return PLUGIN_HANDLED
}
if( g_iDeathMessages[ id ] == false )
{
g_iDeathMessages[ id ] = true
Print( id, "^1You have^4 Enable^3 death messages^1." )
}
else
{
if( g_iDeathMessages[ id ] == true )
{
g_iDeathMessages[ id ] = false
Print( id, "^1You have^4 Disable^3 death messages^1." )
}
}
return PLUGIN_HANDLED
}
public plugin_precache()
{
g_fwid = register_forward( FM_PrecacheEvent, "FwdPrecacheEvent", 1 )
precache_sound( g_szAchievementSound )
#if defined USING_SQL
g_sql_tuple = SQL_MakeStdTuple()
SQL_ThreadQuery(g_sql_tuple, "QueryCreateTable", "CREATE TABLE IF NOT EXISTS ^"Achievement^" ( ^"name^" VARCHAR(32) NOT NULL, ^"authid^" VARCHAR(35) NOT NULL, ^"data^" VARCHAR(256) NOT NULL );" )
#endif
}
public FwdPrecacheEvent( type, const name[] ) {
for( new i = 0; i < sizeof g_iGunEvents; ++i ) {
if( equal( g_iGunEvents[ i ], name ) ) {
g_iGunEvent_IDsBitsum |= ( 1<" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new i = 0; i < 10; i++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_szWeaponNames2[ i ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iPlayersKills[ tempid ][ g_iWeaponIDs[ i ] ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsWeaponMaxKills[ i ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new i = 10; i < 20; i++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_szWeaponNames2[ i ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iPlayersKills[ tempid ][ g_iWeaponIDs[ i ] ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsWeaponMaxKills[ i ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new i = 20; i < WEAPON_SIZE; i++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_szWeaponNames2[ i ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iPlayersKills[ tempid ][ g_iWeaponIDs[ i ] ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsWeaponMaxKills[ i ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new iLevel = 0; iLevel < 10; iLevel++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_iAchsMotd[ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchLevel[ tempid ][ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsMaxPoints[ iLevel ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new iLevel = 10; iLevel < 20; iLevel++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_iAchsMotd[ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchLevel[ tempid ][ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsMaxPoints[ iLevel ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", tempname )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Level" );
len += format( motd[ len ], sizeof( motd ) - len - 1, " | Achievement Max Level" )
for( new iLevel = 20; iLevel < g_iAchCount; iLevel++ )
{
len += format( motd[ len ], sizeof( motd ) - len - 1, " |
" )
len += format( motd[ len ], sizeof( motd ) - len - 1, "%s", g_iAchsMotd[ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchLevel[ tempid ][ iLevel ] )
len += format( motd[ len ], sizeof( motd ) - len - 1, " | %i", g_iAchsMaxPoints[ iLevel ] )
}
len += format( motd[ len ], sizeof( motd ) - len - 1, " |