Такая проблема, в разработка lvl система,чисто дорабатываю скинутую хорошим человеком, подвох в том,что подсчет статистики в lvl систему идет как - то криво, иногда выдается exp одной команде,то второй,иногда убивает человек противника,а EXP дается всем, нужно исправить,что бы 1 килл 1 exp, по коду вроде бы все нормально,прошу знающих помочь
Исходник прикрепил.
P.S LVL система разрабатывается для csdm пушки лазеры,возможно это играет роль
P.S P.S lvl система была изначально для зомби мода,но переписали ее
- Код: Выделить всё
#include < amxmodx >
#include < fakemeta >
#include < hamsandwich >
#include < dhudmessage >
#include < sqlx >
#define MAX_CLIENTS 32
// ТЗ
// файл
// чтение файла
// занесение в массив всех название
// вывод в худе
// и подозреваю оповещение в чат при достижении нового звания с указанием его названия
enum ( += 100 )
{
TASK_SHOWHUD = 4000,
TASK_LOAD_DATA
};
enum _:eData
{
Level = 0,
Experience
};
enum _:STRRANK {
R_NAME[64]
};
new Array:gArrRank;
// CBaseMonster
#define m_LastHitGroup 75
#define USERHUD_NOTICE 250, 128, 114, 0.02, 0.2 // Красный, Зелёный, Синий, X Позиция, Y Позиция
new const iGetExpirenceForKillZombie = 1; // Игрок получит, за убийство зомби
new const iGetExpirenceForKillZombieHead = 2; // Игрок получить, за убийство зомби в голову
new const iExperienceMulti = 1500; // Умножение последующего достижения опыта, для нового уровня (Если не понятно, то ниже пример)
/**
* Формула: { iExperienceMulti * ( Уровень Игрока +1 ) }
*
* Примеры:
* C 50 по 51 уровень, нужно 510 опыта, при iExperienceMulti = 10
* C 76 по 77 уровень, нужно 1925 опыта, при iExperienceMulti = 25
*/
new const iMaxUserLevel = 100; // Максимальный уровень игрока
#define SQL_HOST ""
#define SQL_USER ""
#define SQL_PASSWORD ""
#define SQL_DATABASE ""
#define SQL_TABLENAME "pz_level_csdm"
new g_iUserData[ MAX_CLIENTS +1 ][ eData ];
new bool: g_bUserLoaded[ MAX_CLIENTS +1 ];
new g_szUserSteamID[ MAX_CLIENTS +1 ][ 34 ];
new g_szQuery[ 512 ];
new Handle: g_hDBTuple;
new Handle: g_hConnect;
public plugin_precache() {
ReadRank();
}
public ReadRank() {
gArrRank = ArrayCreate(STRRANK);
//Считываем из файла параметры
new filepatch[256],arrRank[STRRANK];
formatex(filepatch, charsmax(filepatch), "addons/amxmodx/configs/rankname.ini")
if(file_exists(filepatch)) {
static buffer[128];
new iLine, iNum;
for(iLine = 0; read_file(filepatch, iLine, buffer, charsmax(buffer), iNum); iLine++) {
if(iNum > 0 && buffer[0] != '/' && buffer[1] != '/') {
trim(buffer);
formatex(arrRank[R_NAME], charsmax(arrRank[R_NAME]), buffer)
ArrayPushString(gArrRank,arrRank)
}
}
} else {
write_file(filepatch, "//Здесь записывать звания.", 0);
}
}
public plugin_init( ){
register_plugin( "[ZP] Level System", "Best", "t3rkecorejz" );
register_event( "HLTV", "EV_RoundStart", "a", "1=0", "2=0" );
RegisterHam( Ham_Killed, "player", "CPlayer__Killed_Post", .Post = 1 );
}
public plugin_natives( ){
register_native( "ZP_GetUserData", "Native_GetUserData", 1 ); // Получает [0 - Уровень | 1 - Опыт] игрока. Использование: ZP_GetUserData( iPlayer, 0 );
register_native( "ZP_GetUserExpForNextLevel", "Native_GetUserExpForNextLevel", 1 ); // Получает, сколько нужно опыта, для след. уровня. Использование: ZP_GetUserExpForNextLevel( iPlayer );
register_native( "ZP_SetUserData", "Native_SetUserData", 1 ); // Устанавливает [0 - Уровень | 1 - Опыт] игрока. Использование: ZP_SetUserData( iPlayer, 1, 10 );
register_native( "ZP_CheckUserNextLevel", "Native_CheckUserNextLevel", 1 ); // Проверяет, достиг ли игрок нового уровня, если да, то обновляет уровень игрока. Использование: ZP_CheckUserNextLevel( iPlayer );
}
public plugin_cfg( ) SQL_LoadDebug( );
public plugin_end( ) {
if( g_hDBTuple )
SQL_FreeHandle( g_hDBTuple );
if( g_hConnect )
SQL_FreeHandle( g_hConnect );
return;
}
public client_putinserver( iPlayer ) {
set_task( random_float( 1.0, 3.0 ), "CTask__LoadData", iPlayer +TASK_LOAD_DATA );
set_task( 1.0, "CTask__ShowUserHud", iPlayer +TASK_SHOWHUD, _, _, .flags = "b" );
}
public client_disconnect( iPlayer ) {
if( !g_bUserLoaded[ iPlayer ] )
return;
formatex( g_szQuery, charsmax( g_szQuery ), "UPDATE `%s` SET `Level` = '%d', `Experience` = '%d' WHERE `%s`.`SteamID` = '%s';", SQL_TABLENAME, g_iUserData[ iPlayer ][ Level ], g_iUserData[ iPlayer ][ Experience ], SQL_TABLENAME, g_szUserSteamID[ iPlayer ] );
SQL_ThreadQuery( g_hDBTuple, "SQL_ThreadQueryHandler", g_szQuery );
}
// Events
public EV_RoundStart( ) {
for( new iPlayer = 1; iPlayer <= MAX_CLIENTS; iPlayer++ )
{
if( !is_user_connected( iPlayer ) )
continue;
if( !g_bUserLoaded[ iPlayer ] )
return;
formatex( g_szQuery, charsmax( g_szQuery ), "UPDATE `%s` SET `Level` = '%d', `Experience` = '%d' WHERE `%s`.`SteamID` = '%s';", SQL_TABLENAME, g_iUserData[ iPlayer ][ Level ], g_iUserData[ iPlayer ][ Experience ], SQL_TABLENAME, g_szUserSteamID[ iPlayer ] );
SQL_ThreadQuery( g_hDBTuple, "SQL_ThreadQueryHandler", g_szQuery );
}
}
// Ham
public CPlayer__Killed_Post( iVictim, iInflictor, iAttacker ) {
if( !is_user_connected( iVictim ) || !is_user_connected( iAttacker ) || iVictim == iAttacker )
return;
if( g_iUserData[ iAttacker ][ Level ] >= iMaxUserLevel )
return;
if( get_pdata_int( iVictim, m_LastHitGroup, 5 ) == HIT_HEAD )
{
g_iUserData[ iAttacker ][ Experience ] += iGetExpirenceForKillZombieHead;
return;
}
g_iUserData[ iAttacker ][ Experience ] += iGetExpirenceForKillZombie;
Native_CheckUserNextLevel( iAttacker );
return;
}
// Task
public CTask__LoadData( iTask ){
new iPlayer = iTask -TASK_LOAD_DATA;
if( !is_user_connected( iPlayer ) )
return;
new iParams[ 1 ];
iParams [ 0 ] = iPlayer;
get_user_authid( iPlayer, g_szUserSteamID[ iPlayer ], charsmax( g_szUserSteamID[ ] ) );
formatex( g_szQuery, charsmax( g_szQuery ), "SELECT * FROM `%s` WHERE ( `%s`.`SteamID` = '%s' )", SQL_TABLENAME, SQL_TABLENAME, g_szUserSteamID[ iPlayer ] );
SQL_ThreadQuery( g_hDBTuple, "SQL_QueryConnection", g_szQuery, iParams, sizeof iParams );
}
public CTask__ShowUserHud( iTask ){
new iPlayer = iTask -TASK_SHOWHUD;
if( !is_user_alive( iPlayer ) )
return;
new str[64] = "NULL";
new num = g_iUserData[ iPlayer ][ Level ];
if(num < ArraySize(gArrRank)) {
new arrRank[STRRANK];
ArrayGetArray(gArrRank, num, arrRank);
format(str, charsmax(str), "%s", arrRank[R_NAME])
}
set_hudmessage( USERHUD_NOTICE, 0, 0.0, 1.1, 0.0, 0.0, false );
show_hudmessage( iPlayer, "Level: %d | %d%% | Exp: %d/%d | Звание: %s", g_iUserData[ iPlayer ][ Level ], floatround( 99.0 / Native_GetUserExpForNextLevel( iPlayer ) * g_iUserData[ iPlayer ][ Experience ] ), g_iUserData[ iPlayer ][ Experience ], Native_GetUserExpForNextLevel( iPlayer ),str );
}
// MySQL
public SQL_LoadDebug( ) {
new szError[ 512 ];
new iErrorCode;
g_hDBTuple = SQL_MakeDbTuple( SQL_HOST, SQL_USER, SQL_PASSWORD, SQL_DATABASE );
g_hConnect = SQL_Connect( g_hDBTuple, iErrorCode, szError, charsmax( szError ) );
if( g_hConnect == Empty_Handle )
set_fail_state( szError );
if( !SQL_TableExists( g_hConnect, SQL_TABLENAME ) )
{
new Handle: hQueries;
new szQuery[ 512 ];
formatex( szQuery, charsmax( szQuery ), "CREATE TABLE IF NOT EXISTS `%s` ( SteamID varchar( 32 ) CHARACTER SET cp1250 COLLATE cp1250_general_ci NOT NULL, Level INT NOT NULL, Experience INT NOT NULL, PRIMARY KEY ( SteamID ) )", SQL_TABLENAME );
hQueries = SQL_PrepareQuery( g_hConnect, szQuery );
if( !SQL_Execute( hQueries ) )
{
SQL_QueryError( hQueries, szError, charsmax( szError ) );
set_fail_state( szError );
}
SQL_FreeHandle( hQueries );
}
SQL_QueryAndIgnore( g_hConnect, "SET NAMES utf8" );
}
public SQL_QueryConnection( iState, Handle: hQuery, szError[ ], iErrorCode, iParams[ ], iParamsSize ){
switch( iState )
{
case TQUERY_CONNECT_FAILED: log_amx( "Load - Could not connect to SQL database. [%d] %s", iErrorCode, szError );
case TQUERY_QUERY_FAILED: log_amx( "Load Query failed. [%d] %s", iErrorCode, szError );
}
new iPlayer = iParams[ 0 ];
g_bUserLoaded[ iPlayer ] = true;
if( SQL_NumResults( hQuery ) < 1 )
{
if( equal( g_szUserSteamID[ iPlayer ], "ID_PENDING" ) )
return PLUGIN_HANDLED;
g_iUserData[ iPlayer ] = { 1, 0 }
formatex( g_szQuery, charsmax( g_szQuery ), "INSERT INTO `%s` ( `SteamID`, `Level`, `Experience` ) VALUES ( '%s', '%d', '%d' );", SQL_TABLENAME, g_szUserSteamID[ iPlayer ], g_iUserData[ iPlayer ][ Level ], g_iUserData[ iPlayer ][ Experience ] );
SQL_ThreadQuery( g_hDBTuple, "SQL_ThreadQueryHandler", g_szQuery );
return PLUGIN_HANDLED;
}
else
{
g_iUserData[ iPlayer ][ Level ] = SQL_ReadResult( hQuery, 1 );
g_iUserData[ iPlayer ][ Experience ] = SQL_ReadResult( hQuery, 2 );
}
return PLUGIN_HANDLED;
}
public SQL_ThreadQueryHandler( iState, Handle: hQuery, szError[ ], iErrorCode, iParams[ ], iParamsSize ){
if( iState == 0 )
return;
log_amx( "SQL Error: %d (%s)", iErrorCode, szError );
}
// Natives
public Native_GetUserData( iPlayer, iType )
return g_iUserData[ iPlayer ][ iType ];
public Native_GetUserExpForNextLevel( iPlayer )
return iExperienceMulti *( g_iUserData[ iPlayer ][ Level ] +1 );
public Native_SetUserData( iPlayer, iType, iValue )
g_iUserData[ iPlayer ][ iType ] = iValue;
public Native_CheckUserNextLevel( iPlayer ){
if( g_iUserData[ iPlayer ][ Experience ] > Native_GetUserExpForNextLevel( iPlayer ) )
{
g_iUserData[ iPlayer ][ Experience ] -= Native_GetUserExpForNextLevel( iPlayer );
g_iUserData[ iPlayer ][ Level ] += 1;
}
}
// Stocks
stock bool: SQL_TableExists( Handle: hDataBase, const szTable[ ] ){
new Handle: hQuery = SQL_PrepareQuery( hDataBase, "SELECT * FROM information_schema.tables WHERE table_name = '%s' LIMIT 1;", szTable );
new szError[ 512 ];
if( !SQL_Execute( hQuery ) )
{
SQL_QueryError( hQuery, szError, charsmax( szError ) );
set_fail_state( szError );
}
else if( !SQL_NumResults( hQuery ) )
{
SQL_FreeHandle( hQuery );
return false;
}
SQL_FreeHandle( hQuery );
return true;
}